idun-agent-engine 0.1.0__py3-none-any.whl → 0.2.1__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.
Files changed (37) hide show
  1. idun_agent_engine/__init__.py +2 -25
  2. idun_agent_engine/_version.py +1 -1
  3. idun_agent_engine/agent/__init__.py +10 -0
  4. idun_agent_engine/agent/base.py +97 -0
  5. idun_agent_engine/agent/haystack/__init__.py +9 -0
  6. idun_agent_engine/agent/haystack/haystack.py +261 -0
  7. idun_agent_engine/agent/haystack/haystack_model.py +13 -0
  8. idun_agent_engine/agent/haystack/utils.py +13 -0
  9. idun_agent_engine/agent/langgraph/__init__.py +7 -0
  10. idun_agent_engine/agent/langgraph/langgraph.py +429 -0
  11. idun_agent_engine/cli/__init__.py +16 -0
  12. idun_agent_engine/core/__init__.py +11 -0
  13. idun_agent_engine/core/app_factory.py +63 -0
  14. idun_agent_engine/core/config_builder.py +456 -0
  15. idun_agent_engine/core/engine_config.py +22 -0
  16. idun_agent_engine/core/server_runner.py +146 -0
  17. idun_agent_engine/observability/__init__.py +13 -0
  18. idun_agent_engine/observability/base.py +111 -0
  19. idun_agent_engine/observability/langfuse/__init__.py +5 -0
  20. idun_agent_engine/observability/langfuse/langfuse_handler.py +72 -0
  21. idun_agent_engine/observability/phoenix/__init__.py +5 -0
  22. idun_agent_engine/observability/phoenix/phoenix_handler.py +65 -0
  23. idun_agent_engine/observability/phoenix_local/__init__.py +5 -0
  24. idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py +123 -0
  25. idun_agent_engine/py.typed +0 -1
  26. idun_agent_engine/server/__init__.py +5 -0
  27. idun_agent_engine/server/dependencies.py +23 -0
  28. idun_agent_engine/server/lifespan.py +42 -0
  29. idun_agent_engine/server/routers/__init__.py +5 -0
  30. idun_agent_engine/server/routers/agent.py +68 -0
  31. idun_agent_engine/server/routers/base.py +60 -0
  32. idun_agent_engine/server/server_config.py +8 -0
  33. idun_agent_engine-0.2.1.dist-info/METADATA +278 -0
  34. idun_agent_engine-0.2.1.dist-info/RECORD +35 -0
  35. {idun_agent_engine-0.1.0.dist-info → idun_agent_engine-0.2.1.dist-info}/WHEEL +1 -1
  36. idun_agent_engine-0.1.0.dist-info/METADATA +0 -317
  37. idun_agent_engine-0.1.0.dist-info/RECORD +0 -6
@@ -0,0 +1,111 @@
1
+ """Observability base classes and factory functions.
2
+
3
+ Defines the provider-agnostic interface and a factory to create handlers.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ from abc import ABC, abstractmethod
10
+ from typing import Any
11
+
12
+ from idun_agent_schema.engine.observability import ObservabilityConfig
13
+
14
+
15
+ class ObservabilityHandlerBase(ABC):
16
+ """Abstract base class for observability handlers.
17
+
18
+ Concrete implementations must provide provider name and callbacks.
19
+ """
20
+
21
+ provider: str
22
+
23
+ def __init__(self, options: dict[str, Any] | None = None) -> None:
24
+ """Initialize handler with provider-specific options."""
25
+ self.options: dict[str, Any] = options or {}
26
+
27
+ @abstractmethod
28
+ def get_callbacks(self) -> list[Any]:
29
+ """Return a list of callbacks (can be empty)."""
30
+ raise NotImplementedError
31
+
32
+ def get_run_name(self) -> str | None:
33
+ """Optional run name used by frameworks that support it."""
34
+ run_name = self.options.get("run_name")
35
+ return run_name if isinstance(run_name, str) else None
36
+
37
+
38
+ def _normalize_config(
39
+ config: ObservabilityConfig | dict[str, Any] | None,
40
+ ) -> dict[str, Any]:
41
+ if config is None:
42
+ return {"enabled": False}
43
+ if isinstance(config, ObservabilityConfig):
44
+ resolved = config.resolved()
45
+ return {
46
+ "provider": resolved.provider,
47
+ "enabled": resolved.enabled,
48
+ "options": resolved.options,
49
+ }
50
+ # Assume dict-like
51
+ provider = (config or {}).get("provider")
52
+ enabled = bool((config or {}).get("enabled", False))
53
+ options = dict((config or {}).get("options", {}))
54
+ return {"provider": provider, "enabled": enabled, "options": options}
55
+
56
+
57
+ def create_observability_handler(
58
+ config: ObservabilityConfig | dict[str, Any] | None,
59
+ ) -> tuple[ObservabilityHandlerBase | None, dict[str, Any] | None]:
60
+ """Factory to create an observability handler based on provider.
61
+
62
+ Accepts either an `ObservabilityConfig` or a raw dict.
63
+ Returns (handler, info_dict). info_dict can be attached to agent infos for debugging.
64
+ """
65
+ normalized = _normalize_config(config)
66
+ provider = normalized.get("provider")
67
+ enabled = normalized.get("enabled", False)
68
+ options: dict[str, Any] = normalized.get("options", {})
69
+
70
+ if not enabled or not provider:
71
+ return None, {"enabled": False}
72
+
73
+ if provider == "langfuse":
74
+ from .langfuse.langfuse_handler import LangfuseHandler
75
+
76
+ handler = LangfuseHandler(options)
77
+ return handler, {
78
+ "enabled": True,
79
+ "provider": "langfuse",
80
+ "host": os.getenv("LANGFUSE_HOST"),
81
+ "run_name": handler.get_run_name(),
82
+ }
83
+
84
+ if provider == "phoenix":
85
+ from .phoenix.phoenix_handler import PhoenixHandler
86
+
87
+ handler = PhoenixHandler(options)
88
+ info: dict[str, Any] = {
89
+ "enabled": True,
90
+ "provider": "phoenix",
91
+ "collector": os.getenv("PHOENIX_COLLECTOR_ENDPOINT"),
92
+ }
93
+ project_name = getattr(handler, "project_name", None)
94
+ if project_name:
95
+ info["project_name"] = project_name
96
+ return handler, info
97
+
98
+ if provider == "phoenix-local":
99
+ from .phoenix_local.phoenix_local_handler import PhoenixLocalHandler
100
+
101
+ handler = PhoenixLocalHandler(options)
102
+ return handler, {
103
+ "enabled": True,
104
+ "provider": "phoenix-local",
105
+ }
106
+
107
+ return None, {
108
+ "enabled": False,
109
+ "provider": provider,
110
+ "error": "Unsupported provider",
111
+ }
@@ -0,0 +1,5 @@
1
+ """Langfuse observability integration package."""
2
+
3
+ from .langfuse_handler import LangfuseHandler
4
+
5
+ __all__ = ["LangfuseHandler"]
@@ -0,0 +1,72 @@
1
+ """Langfuse observability handler implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ from idun_agent_schema.engine.observability import _resolve_env
9
+
10
+ from ..base import ObservabilityHandlerBase
11
+
12
+
13
+ class LangfuseHandler(ObservabilityHandlerBase):
14
+ """Langfuse handler providing LangChain callbacks and client setup."""
15
+
16
+ provider = "langfuse"
17
+
18
+ def __init__(self, options: dict[str, Any] | None = None):
19
+ """Initialize handler, resolving env and preparing callbacks."""
20
+ super().__init__(options)
21
+ opts = self.options
22
+
23
+ # Resolve and set env vars as required by Langfuse
24
+ host = self._resolve_env(opts.get("host")) or os.getenv("LANGFUSE_HOST")
25
+ public_key = self._resolve_env(opts.get("public_key")) or os.getenv(
26
+ "LANGFUSE_PUBLIC_KEY"
27
+ )
28
+ secret_key = self._resolve_env(opts.get("secret_key")) or os.getenv(
29
+ "LANGFUSE_SECRET_KEY"
30
+ )
31
+
32
+ if host:
33
+ os.environ["LANGFUSE_HOST"] = host
34
+ if public_key:
35
+ os.environ["LANGFUSE_PUBLIC_KEY"] = public_key
36
+ if secret_key:
37
+ os.environ["LANGFUSE_SECRET_KEY"] = secret_key
38
+
39
+ # Instantiate callback handler lazily to avoid hard dep if not installed
40
+ self._callbacks: list[Any] = []
41
+ self._langfuse_client = None
42
+ try:
43
+ from langfuse.callback import CallbackHandler
44
+ from langfuse.client import Langfuse
45
+
46
+ self._langfuse_client = Langfuse()
47
+
48
+ try:
49
+ if self._langfuse_client.auth_check():
50
+ print("Langfuse client is authenticated and ready!")
51
+ else:
52
+ print(
53
+ "Authentication failed. Please check your credentials and host."
54
+ )
55
+ except Exception:
56
+ pass
57
+
58
+ self._callbacks = [CallbackHandler()]
59
+ except Exception:
60
+ self._callbacks = []
61
+
62
+ @staticmethod
63
+ def _resolve_env(value: str | None) -> str | None:
64
+ return _resolve_env(value)
65
+
66
+ def get_callbacks(self) -> list[Any]:
67
+ """Return LangChain-compatible callback handlers (if available)."""
68
+ return self._callbacks
69
+
70
+ def get_client(self):
71
+ """Return underlying Langfuse client instance (if created)."""
72
+ return self._langfuse_client
@@ -0,0 +1,5 @@
1
+ """Arize Phoenix observability integration package."""
2
+
3
+ from .phoenix_handler import PhoenixHandler
4
+
5
+ __all__ = ["PhoenixHandler"]
@@ -0,0 +1,65 @@
1
+ """Phoenix observability handler implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ from idun_agent_schema.engine.observability import _resolve_env
9
+
10
+ from ..base import ObservabilityHandlerBase
11
+
12
+
13
+ class PhoenixHandler(ObservabilityHandlerBase):
14
+ """Phoenix handler configuring OpenTelemetry and LangChain instrumentation."""
15
+
16
+ provider = "phoenix"
17
+
18
+ def __init__(self, options: dict[str, Any] | None = None):
19
+ """Initialize handler, resolving env and setting up instrumentation."""
20
+ super().__init__(options)
21
+ opts = self.options
22
+
23
+ # Resolve and set env vars as required by Phoenix
24
+ api_key = self._resolve_env(opts.get("api_key")) or os.getenv("PHOENIX_API_KEY")
25
+ collector = (
26
+ self._resolve_env(opts.get("collector"))
27
+ or self._resolve_env(opts.get("collector_endpoint"))
28
+ or os.getenv("PHOENIX_COLLECTOR_ENDPOINT")
29
+ )
30
+ self.project_name: str = opts.get("project_name") or "default"
31
+
32
+ if api_key:
33
+ os.environ["PHOENIX_API_KEY"] = api_key
34
+ if collector:
35
+ os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = collector
36
+
37
+ # Some older Phoenix deployments (before 2025-06-24) require setting client headers.
38
+ # If not explicitly provided, set it from API key when available for backward compatibility.
39
+ client_headers = opts.get("client_headers")
40
+ if isinstance(client_headers, str) and client_headers:
41
+ os.environ["PHOENIX_CLIENT_HEADERS"] = client_headers
42
+ elif api_key and not os.getenv("PHOENIX_CLIENT_HEADERS"):
43
+ os.environ["PHOENIX_CLIENT_HEADERS"] = f"api_key={api_key}"
44
+
45
+ # Configure tracer provider using phoenix.otel.register
46
+ self._callbacks: list[Any] = []
47
+ try:
48
+ from openinference.instrumentation.langchain import LangChainInstrumentor
49
+ from phoenix.otel import register # type: ignore
50
+
51
+ tracer_provider = register(
52
+ project_name=self.project_name, auto_instrument=True
53
+ )
54
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
55
+ except Exception:
56
+ # Silent failure; user may not have phoenix installed
57
+ pass
58
+
59
+ @staticmethod
60
+ def _resolve_env(value: str | None) -> str | None:
61
+ return _resolve_env(value)
62
+
63
+ def get_callbacks(self) -> list[Any]:
64
+ """Return callbacks (Phoenix instruments globally; this may be empty)."""
65
+ return self._callbacks
@@ -0,0 +1,5 @@
1
+ """Arize Phoenix observability integration package."""
2
+
3
+ from .phoenix_local_handler import PhoenixLocalHandler
4
+
5
+ __all__ = ["PhoenixLocalHandler"]
@@ -0,0 +1,123 @@
1
+ """Phoenix observability handler implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import os
7
+ import shlex
8
+ import subprocess
9
+ from typing import Any
10
+
11
+ from idun_agent_schema.engine.observability import _resolve_env
12
+
13
+ from ..base import ObservabilityHandlerBase
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class PhoenixLocalHandler(ObservabilityHandlerBase):
19
+ """Phoenix handler configuring OpenTelemetry and LangChain instrumentation."""
20
+
21
+ provider = "phoenix-local"
22
+
23
+ def __init__(
24
+ self,
25
+ options: dict[str, Any] | None = None,
26
+ default_endpoint: str = "http://127.0.0.1:6006",
27
+ ):
28
+ """Initialize handler, start Phoenix via CLI, and set up instrumentation.
29
+
30
+ Args:
31
+ options: Configuration options dictionary
32
+ default_endpoint: Default Phoenix collector endpoint URL
33
+ """
34
+ logger.info("Initializing PhoenixLocalHandler")
35
+
36
+ super().__init__(options)
37
+ opts = self.options or {}
38
+
39
+ # Initialize instance variables
40
+ self._callbacks: list[Any] = []
41
+ self._proc: subprocess.Popen[bytes] | None = None
42
+ self.default_endpoint = default_endpoint
43
+ self.project_name: str = "default"
44
+
45
+ self._configure_collector_endpoint(opts)
46
+ self._start_phoenix_cli()
47
+
48
+ try:
49
+ from openinference.instrumentation.langchain import LangChainInstrumentor
50
+ from phoenix.otel import register
51
+
52
+ logger.debug("Successfully imported Phoenix dependencies")
53
+
54
+ self.project_name = opts.get("project_name") or "default"
55
+ logger.info(f"Using project name: {self.project_name}")
56
+
57
+ tracer_provider = register(
58
+ project_name=self.project_name, auto_instrument=True
59
+ )
60
+
61
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
62
+
63
+ except ImportError as e:
64
+ logger.error(f"Missing required Phoenix dependencies: {e}")
65
+ raise ImportError(f"Phoenix dependencies not found: {e}. ") from e
66
+
67
+ except Exception as e:
68
+ logger.error(f"Failed to set up Phoenix instrumentation: {e}")
69
+ raise RuntimeError(f"Phoenix instrumentation setup failed: {e}") from e
70
+
71
+ logger.info("Phoenix local handler initialized...")
72
+
73
+ def _configure_collector_endpoint(self, opts: dict[str, Any]) -> None:
74
+ """Configure the Phoenix collector endpoint from various sources."""
75
+ logger.debug("Configuring collector endpoint")
76
+
77
+ collector = (
78
+ self._resolve_env(opts.get("collector"))
79
+ or self._resolve_env(opts.get("collector_endpoint"))
80
+ or os.getenv("PHOENIX_COLLECTOR_ENDPOINT")
81
+ or self.default_endpoint
82
+ )
83
+
84
+ logger.info(f"Setting Phoenix collector endpoint to: {collector}")
85
+ os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = collector
86
+ self.collector_endpoint = collector
87
+
88
+ def _start_phoenix_cli(self) -> None:
89
+ """Start pheonix subprocess."""
90
+ try:
91
+ cmd = "phoenix serve"
92
+ logger.debug(f"Executing command: {cmd}")
93
+
94
+ self._proc = subprocess.Popen(
95
+ shlex.split(cmd),
96
+ stdout=subprocess.DEVNULL,
97
+ stderr=subprocess.DEVNULL,
98
+ start_new_session=True,
99
+ )
100
+
101
+ logger.info(f"Phoenix server started with PID: {self._proc.pid}")
102
+
103
+ except FileNotFoundError as e:
104
+ logger.error(f"Phoenix CLI not found. Make sure Phoenix is installed : {e}")
105
+ self._proc = None
106
+
107
+ except subprocess.SubprocessError as e:
108
+ logger.error(f"Failed to start Phoenix CLI subprocess: {e}")
109
+ self._proc = None
110
+
111
+ except Exception as e:
112
+ logger.error(f"Unexpected error starting Phoenix CLI: {e}")
113
+ self._proc = None
114
+
115
+ @staticmethod
116
+ def _resolve_env(value: str | None) -> str | None:
117
+ """Resolve environment variable value."""
118
+ return _resolve_env(value)
119
+
120
+ def get_callbacks(self) -> list[Any]:
121
+ """Return callbacks (Phoenix instruments globally; this may be empty)."""
122
+ logger.debug("Getting callbacks (Phoenix uses global instrumentation)")
123
+ return self._callbacks
@@ -1 +0,0 @@
1
- # Marker file to indicate that this package is PEP 561 typed
@@ -0,0 +1,5 @@
1
+ """Server package for FastAPI app components and configuration."""
2
+
3
+ from . import dependencies, lifespan, server_config
4
+
5
+ __all__ = ["server_config", "dependencies", "lifespan"]
@@ -0,0 +1,23 @@
1
+ """Dependency injection helpers for FastAPI routes."""
2
+
3
+ from fastapi import Request
4
+
5
+ from ..core.config_builder import ConfigBuilder
6
+
7
+
8
+ async def get_agent(request: Request):
9
+ """Return the pre-initialized agent instance from the app state.
10
+
11
+ Falls back to loading from the default config if not present (e.g., tests).
12
+ """
13
+ if hasattr(request.app.state, "agent"):
14
+ return request.app.state.agent
15
+ else:
16
+ # This is a fallback for cases where the lifespan event did not run,
17
+ # like in some testing scenarios.
18
+ # Consider logging a warning here.
19
+ print("⚠️ Agent not found in app state, initializing fallback agent...")
20
+
21
+ app_config = ConfigBuilder.load_from_file()
22
+ agent = await ConfigBuilder.initialize_agent_from_config(app_config)
23
+ return agent
@@ -0,0 +1,42 @@
1
+ """Server lifespan management utilities.
2
+
3
+ Initializes the agent at startup and cleans up resources on shutdown.
4
+ """
5
+
6
+ import inspect
7
+ from contextlib import asynccontextmanager
8
+
9
+ from fastapi import FastAPI
10
+
11
+ from ..core.config_builder import ConfigBuilder
12
+
13
+
14
+ @asynccontextmanager
15
+ async def lifespan(app: FastAPI):
16
+ """FastAPI lifespan context to initialize and teardown the agent."""
17
+ # Load config and initialize agent on startup
18
+ print("Server starting up...")
19
+ engine_config = app.state.engine_config
20
+
21
+ # Use ConfigBuilder's centralized agent initialization
22
+ agent_instance = await ConfigBuilder.initialize_agent_from_config(engine_config)
23
+
24
+ # Store both in app state
25
+ app.state.agent = agent_instance
26
+ app.state.config = engine_config
27
+
28
+ agent_name = getattr(agent_instance, "name", "Unknown")
29
+ print(f"✅ Agent '{agent_name}' initialized and ready to serve!")
30
+
31
+ yield
32
+
33
+ # Clean up on shutdown
34
+ print("🔄 Idun Agent Engine shutting down...")
35
+ agent = getattr(app.state, "agent", None)
36
+ if agent is not None:
37
+ close_fn = getattr(agent, "close", None)
38
+ if callable(close_fn):
39
+ result = close_fn()
40
+ if inspect.isawaitable(result):
41
+ await result
42
+ print("✅ Agent resources cleaned up successfully.")
@@ -0,0 +1,5 @@
1
+ """FastAPI routers for the engine service."""
2
+
3
+ from . import agent, base
4
+
5
+ __all__ = ["agent", "base"]
@@ -0,0 +1,68 @@
1
+ """Agent routes for invoking and streaming agent responses."""
2
+
3
+ import logging
4
+ from typing import Annotated
5
+
6
+ from fastapi import APIRouter, Depends, HTTPException, Request, status
7
+ from fastapi.responses import StreamingResponse
8
+ from idun_agent_schema.engine.api import ChatRequest, ChatResponse
9
+
10
+ from idun_agent_engine.agent.base import BaseAgent
11
+ from idun_agent_engine.server.dependencies import get_agent
12
+
13
+ logging.basicConfig(
14
+ format="%(asctime)s %(levelname)-8s %(message)s",
15
+ level=logging.INFO,
16
+ datefmt="%Y-%m-%d %H:%M:%S",
17
+ )
18
+
19
+ logger = logging.getLogger(__name__)
20
+ agent_router = APIRouter()
21
+
22
+
23
+ @agent_router.get("/config")
24
+ async def get_config(request: Request):
25
+ """Get the current agent configuration."""
26
+ logger.debug("Fetching agent config..")
27
+ if not hasattr(request.app.state, "engine_config"):
28
+ logger.error("Error retrieving the engine config from the api. ")
29
+ raise HTTPException(
30
+ status_code=status.HTTP_404_NOT_FOUND, detail="Configuration not available"
31
+ )
32
+
33
+ config = request.app.state.engine_config.agent
34
+ logger.info(f"Fetched config for agent: {config}")
35
+ return {"config": config}
36
+
37
+
38
+ @agent_router.post("/invoke", response_model=ChatResponse)
39
+ async def invoke(
40
+ request: ChatRequest,
41
+ agent: Annotated[BaseAgent, Depends(get_agent)],
42
+ ):
43
+ """Process a chat message with the agent without streaming."""
44
+ try:
45
+ message = {"query": request.query, "session_id": request.session_id}
46
+ response_content = await agent.invoke(message)
47
+
48
+ return ChatResponse(session_id=request.session_id, response=response_content)
49
+ except Exception as e: # noqa: BLE001
50
+ raise HTTPException(status_code=500, detail=str(e)) from e
51
+
52
+
53
+ @agent_router.post("/stream")
54
+ async def stream(
55
+ request: ChatRequest,
56
+ agent: Annotated[BaseAgent, Depends(get_agent)],
57
+ ):
58
+ """Process a message with the agent, streaming ag-ui events."""
59
+ try:
60
+
61
+ async def event_stream():
62
+ message = {"query": request.query, "session_id": request.session_id}
63
+ async for event in agent.stream(message):
64
+ yield f"data: {event.model_dump_json()}\n\n"
65
+
66
+ return StreamingResponse(event_stream(), media_type="text/event-stream")
67
+ except Exception as e: # noqa: BLE001
68
+ raise HTTPException(status_code=500, detail=str(e)) from e
@@ -0,0 +1,60 @@
1
+ """Base routes for service health and landing info."""
2
+
3
+ from fastapi import APIRouter
4
+
5
+ from ..._version import __version__
6
+
7
+ base_router = APIRouter()
8
+
9
+
10
+ @base_router.get("/health")
11
+ def health_check():
12
+ """Health check endpoint for monitoring and load balancers."""
13
+ return {"status": "healthy", "engine_version": __version__}
14
+
15
+
16
+ # Add a root endpoint with helpful information
17
+ @base_router.get("/")
18
+ def read_root():
19
+ """Root endpoint with basic information about the service."""
20
+ return {
21
+ "message": "Welcome to your Idun Agent Engine server!",
22
+ "docs": "/docs",
23
+ "health": "/health",
24
+ "agent_endpoints": {"invoke": "/agent/invoke", "stream": "/agent/stream"},
25
+ }
26
+
27
+
28
+ # # Add info endpoint for detailed server and agent information
29
+ # @base_router.get("/info")
30
+ # def get_info(request: Request):
31
+ # """Get detailed information about the server and loaded agent."""
32
+ # info = {
33
+ # "engine": {
34
+ # "name": "Idun Agent Engine",
35
+ # "version": __version__,
36
+ # "description": "A framework for building and deploying conversational AI agents"
37
+ # },
38
+ # "server": {
39
+ # "status": "running",
40
+ # "endpoints": {
41
+ # "health": "/health",
42
+ # "docs": "/docs",
43
+ # "redoc": "/redoc",
44
+ # "agent_invoke": "/agent/invoke",
45
+ # "agent_stream": "/agent/stream"
46
+ # }
47
+ # }
48
+ # }
49
+
50
+ # # Add agent information if available in app state
51
+ # if hasattr(request.app.state, "config") and request.app.state.config:
52
+ # config = request.app.state.config
53
+ # info["agent"] = {
54
+ # "type": config.agent.type,
55
+ # "name": config.agent.config.get("name", "Unknown"),
56
+ # "status": "loaded"
57
+ # }
58
+ # info["server"]["port"] = config.server.api.port
59
+
60
+ # return info
@@ -0,0 +1,8 @@
1
+ """Compatibility re-exports for server configuration models."""
2
+
3
+ from idun_agent_schema.engine.server import ( # noqa: F401
4
+ ServerAPIConfig,
5
+ ServerConfig,
6
+ )
7
+
8
+ __all__ = ["ServerAPIConfig", "ServerConfig"]