@@ -24,24 +24,69 @@ def _requirements() -> str:
2424
2525
2626def _main_py (name : str ) -> str :
27- """Return a starter ``main.py`` with an explicit AgentPlatform config."""
27+ """Return a starter ``main.py`` whose module-level ``app`` matches ``run``.
28+
29+ The generated module exposes ``app = platform.build()`` so a deployed
30+ container (``uvicorn main:app``) serves the exact same feature set as
31+ ``agentomatic run`` (Studio, docs, health, metrics, all component dirs).
32+ Every feature is driven from ``AGENTOMATIC_*`` env vars, so the same file
33+ works unchanged in dev and in production without code edits.
34+
35+ Args:
36+ name: Project directory / display name.
37+
38+ Returns:
39+ Rendered ``main.py`` source.
40+ """
2841 display = name .replace ("_" , " " ).title ()
2942 return f'''"""{ name } — Agentomatic platform entrypoint.
3043
31- Edit the AgentPlatform kwargs below to enable auth, metrics, stores, etc.
32- Stacks in ``stacks/`` supply LLM / embedding / DB defaults — switch with::
44+ Serves an identical feature set whether launched with ``agentomatic run``
45+ (dev) or ``uvicorn main:app`` (container). Toggle features with
46+ ``AGENTOMATIC_*`` env vars — no code edits required. Stacks in ``stacks/``
47+ supply LLM / embedding / DB defaults — switch with::
3348
3449 agentomatic stack use local # or remote
3550"""
3651from __future__ import annotations
3752
53+ import os
54+
3855from agentomatic import AgentPlatform
3956
4057# Optional: SQLAlchemyStore, MemoryStore, connection configs, JWTConfig, …
4158
4259
60+ def _env_bool(var: str, default: bool) -> bool:
61+ """Parse a boolean feature flag from the environment.
62+
63+ Args:
64+ var: Environment variable name.
65+ default: Value used when the variable is unset or empty.
66+
67+ Returns:
68+ ``True`` for ``1/true/yes/on`` (case-insensitive), else ``False``.
69+ """
70+ raw = os.getenv(var)
71+ if raw is None or raw == "":
72+ return default
73+ return raw.strip().lower() in {{"1", "true", "yes", "on"}}
74+
75+
4376def create_platform() -> AgentPlatform:
44- """Build the platform from discovered agents/plugins/endpoints/ingestion."""
77+ """Build a fully-featured platform matching ``agentomatic run`` defaults.
78+
79+ Discovers every component directory (agents, plugins, endpoints, ingestion,
80+ pipelines, stacks) and enables Studio, docs, health, and metrics by default.
81+ Auth, control plane, and rate limiting stay opt-in via ``AGENTOMATIC_*``
82+ env vars so the deployed container is configurable without code changes.
83+
84+ Returns:
85+ A configured :class:`AgentPlatform` ready to :meth:`build`.
86+ """
87+ # ``require_auth`` mirrors ``agentomatic run --require-auth-globally``:
88+ # it implies zero-trust + JWT unless those are overridden individually.
89+ require_auth = _env_bool("AGENTOMATIC_REQUIRE_AUTH", False)
4590 return AgentPlatform.from_folder(
4691 "agents/",
4792 plugins_dir="plugins/",
@@ -50,18 +95,21 @@ def create_platform() -> AgentPlatform:
5095 stacks_dir="stacks/",
5196 # Pipelines are auto-discovered from ../pipelines/ (sibling of agents/).
5297 # stack="local", # or set via .agentomatic-stack / STACK env
53- title=" { display } Platform",
98+ title=os.getenv("AGENTOMATIC_TITLE", " { display } Platform") ,
5499 description="Agentomatic multi-agent platform for { name } ",
55- enable_studio=True,
56- enable_metrics=True,
57- # enable_auth=True,
58- # auth_api_key="${{API_KEY}}", # prefer env / stack auth
59- # enable_jwt_auth=True, # set jwt_config / JWKS via stack
60- # enable_zero_trust=True,
61- # require_auth_globally=False, # needs JWT or API-key auth wired
62- # enable_control_plane=True,
63- # control_token="${{CONTROL_TOKEN}}",
64- # enable_rate_limit=True,
100+ log_level=os.getenv("AGENTOMATIC_LOG_LEVEL", "INFO"),
101+ # On by default — matches `agentomatic run` (Studio) + prod observability.
102+ enable_studio=_env_bool("AGENTOMATIC_ENABLE_STUDIO", True),
103+ enable_metrics=_env_bool("AGENTOMATIC_ENABLE_METRICS", True),
104+ # Opt-in hardening — drive from env / stack; no code edits needed.
105+ enable_auth=_env_bool("AGENTOMATIC_ENABLE_AUTH", False),
106+ auth_api_key=os.getenv("AGENTOMATIC_API_KEY", ""),
107+ enable_jwt_auth=_env_bool("AGENTOMATIC_ENABLE_JWT", require_auth),
108+ enable_zero_trust=_env_bool("AGENTOMATIC_ENABLE_ZERO_TRUST", require_auth),
109+ require_auth_globally=require_auth,
110+ enable_control_plane=_env_bool("AGENTOMATIC_ENABLE_CONTROL_PLANE", False),
111+ control_token=os.getenv("AGENTOMATIC_CONTROL_TOKEN", ""),
112+ enable_rate_limit=_env_bool("AGENTOMATIC_ENABLE_RATE_LIMIT", False),
65113 )
66114
67115
@@ -70,7 +118,10 @@ def create_platform() -> AgentPlatform:
70118
71119
72120if __name__ == "__main__":
73- _platform.run(host="0.0.0.0", port=8000)
121+ _platform.run(
122+ host=os.getenv("AGENTOMATIC_HOST", "0.0.0.0"),
123+ port=int(os.getenv("AGENTOMATIC_PORT", "8000")),
124+ )
74125'''
75126
76127
@@ -130,6 +181,20 @@ def _env_example() -> str:
130181# Active stack (optional; prefer: agentomatic stack use local)
131182# AGENTOMATIC_STACK=local
132183
184+ # --- Deploy feature flags (main.py reads these; parity with `agentomatic run`) ---
185+ # Studio + metrics are ON by default; auth/control-plane/rate-limit are opt-in.
186+ # AGENTOMATIC_TITLE=My Platform
187+ # AGENTOMATIC_LOG_LEVEL=INFO
188+ # AGENTOMATIC_ENABLE_STUDIO=1
189+ # AGENTOMATIC_ENABLE_METRICS=1
190+ # AGENTOMATIC_ENABLE_AUTH=0 # API-key auth (needs AGENTOMATIC_API_KEY)
191+ # AGENTOMATIC_ENABLE_JWT=0 # JWT auth (set JWKS via stack)
192+ # AGENTOMATIC_REQUIRE_AUTH=0 # implies JWT + zero-trust; needs auth wired
193+ # AGENTOMATIC_ENABLE_CONTROL_PLANE=0 # needs AGENTOMATIC_CONTROL_TOKEN
194+ # AGENTOMATIC_ENABLE_RATE_LIMIT=0
195+ # AGENTOMATIC_API_KEY=
196+ # AGENTOMATIC_CONTROL_TOKEN=
197+
133198# --- LLM providers ---
134199OPENAI_API_KEY=
135200AZURE_OPENAI_API_KEY=
0 commit comments