From 4ea775817370e548b98b164964c210cc5517b1fa Mon Sep 17 00:00:00 2001 From: PRAMOD B N Date: Fri, 14 Aug 2026 21:48:15 -0500 Subject: [PATCH] Add concept doc, README, ROADMAP, and v0.0.1 implementation scaffold - Architecture concept doc, README, ROADMAP, AGENTS.md dev reference - Package scaffold: models, in-memory registry, discovery, read-only API facade, CLI/console/config placeholders, thin adapter catalog - Tests, examples, CI + PyPI release workflows, contributing/security docs --- .github/CODEOWNERS | 2 + .github/dependabot.yml | 11 + .github/workflows/ci.yml | 60 ++ .github/workflows/release-pypi.yml | 47 + .gitignore | 13 + AGENTS.md | 180 ++++ CHANGELOG.md | 8 + CI.md | 13 + CONTRIBUTING.md | 26 + DeepAgent-Control-Tower-Concept.md | 990 ++++++++++++++++++ LICENSE | 22 + Makefile | 37 + README.md | 240 ++++- ROADMAP.md | 368 +++++++ SECURITY.md | 14 + docs/architecture.md | 15 + examples/sample_agent_registration.json | 15 + pyproject.toml | 102 ++ src/agenticops_control_tower/__init__.py | 5 + .../adapters/__init__.py | 5 + .../adapters/catalog.py | 8 + src/agenticops_control_tower/api/__init__.py | 5 + src/agenticops_control_tower/api/surface.py | 28 + src/agenticops_control_tower/cli/__init__.py | 1 + src/agenticops_control_tower/cli/main.py | 11 + .../config/__init__.py | 5 + src/agenticops_control_tower/config/models.py | 19 + .../console/__init__.py | 1 + src/agenticops_control_tower/console/app.py | 7 + .../discovery/__init__.py | 5 + .../discovery/service.py | 17 + .../models/__init__.py | 5 + src/agenticops_control_tower/models/agent.py | 38 + .../registry/__init__.py | 5 + .../registry/service.py | 29 + tests/test_imports.py | 17 + tests/test_registry.py | 38 + 37 files changed, 2411 insertions(+), 1 deletion(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release-pypi.yml create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 CHANGELOG.md create mode 100644 CI.md create mode 100644 CONTRIBUTING.md create mode 100644 DeepAgent-Control-Tower-Concept.md create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 ROADMAP.md create mode 100644 SECURITY.md create mode 100644 docs/architecture.md create mode 100644 examples/sample_agent_registration.json create mode 100644 pyproject.toml create mode 100644 src/agenticops_control_tower/__init__.py create mode 100644 src/agenticops_control_tower/adapters/__init__.py create mode 100644 src/agenticops_control_tower/adapters/catalog.py create mode 100644 src/agenticops_control_tower/api/__init__.py create mode 100644 src/agenticops_control_tower/api/surface.py create mode 100644 src/agenticops_control_tower/cli/__init__.py create mode 100644 src/agenticops_control_tower/cli/main.py create mode 100644 src/agenticops_control_tower/config/__init__.py create mode 100644 src/agenticops_control_tower/config/models.py create mode 100644 src/agenticops_control_tower/console/__init__.py create mode 100644 src/agenticops_control_tower/console/app.py create mode 100644 src/agenticops_control_tower/discovery/__init__.py create mode 100644 src/agenticops_control_tower/discovery/service.py create mode 100644 src/agenticops_control_tower/models/__init__.py create mode 100644 src/agenticops_control_tower/models/agent.py create mode 100644 src/agenticops_control_tower/registry/__init__.py create mode 100644 src/agenticops_control_tower/registry/service.py create mode 100644 tests/test_imports.py create mode 100644 tests/test_registry.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..6914fc2 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +* @DeepAgentLabs + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..173bea9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b8c9046 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + steps: + - uses: actions/checkout@v7 + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync --extra dev --python ${{ matrix.python-version }} + + - name: Lint (ruff check) + run: uv run ruff check src tests + + # Scoped to src/tests, not ".". The repo docs intentionally contain + # pseudocode and architecture snippets that are not meant to be treated + # as executable Python by the formatter. + - name: Format check (ruff format) + run: uv run ruff format --check src tests + + - name: Type check (mypy) + run: uv run mypy + + - name: Test (pytest) + run: uv run pytest + + package: + runs-on: ubuntu-latest + needs: [test] + steps: + - uses: actions/checkout@v7 + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + - name: Set up Python + run: uv python install 3.12 + - name: Install dependencies + run: uv sync --extra dev --python 3.12 + - name: Build distributions + run: | + uv run python -m build + uv run python -m twine check dist/* + diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml new file mode 100644 index 0000000..3559615 --- /dev/null +++ b/.github/workflows/release-pypi.yml @@ -0,0 +1,47 @@ +name: publish-pypi + +on: + release: + types: [published] + push: + tags: + - "v*" + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Build distributions + run: | + python -m pip install --upgrade pip + python -m pip install build twine + python -m build + python -m twine check dist/* + - name: Upload distributions + uses: actions/upload-artifact@v7 + with: + name: python-package-distributions + path: dist/ + + publish-pypi: + runs-on: ubuntu-latest + needs: build + environment: pypi + permissions: + id-token: write + steps: + - name: Download distributions + uses: actions/download-artifact@v8 + with: + name: python-package-distributions + path: dist/ + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cedfa88 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +__pycache__/ +*.py[cod] +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ +.coverage +htmlcov/ +dist/ +build/ +*.egg-info/ +.venv/ +.DS_Store + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..a3dddc7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,180 @@ +## agenticops-control-tower Development Reference + +## Ecosystem Context + +### Role in DeepAgentLabs + +`agenticops-control-tower` is the operations and control-plane layer in the +DeepAgentLabs ecosystem. Its job is to centralize inventory, visibility, +configuration, and operator workflows across many deployed agents and many +DeepAgentLabs capabilities. + +### Owns + +- Agent registry, heartbeat, and fleet-inventory concerns +- Capability discovery and version/status visibility across deployed agents +- The unified control-plane API, CLI, and future console surface +- Thin ecosystem adapters that summarize sibling-package posture without + re-implementing sibling-package logic + +### Does Not Own + +- The canonical operational schema or shared normative object model — that + belongs in `ai-operations-spec` +- Core observability, profiling, evaluation, or recommendation logic — that + belongs in `agenticlens` +- Fault injection and resilience-testing logic — that belongs in + `agentic-chaos` +- Decision-time governance or pre-action intervention logic — that belongs in + `agentic-sidecar` +- The MCP-native access surface itself — that belongs in + `deep-agentic-core-mcp`, even when it later connects to Control Tower + +### Integrates With + +- `ai-operations-spec` for shared terminology and any ecosystem-facing + inventory, status, or configuration contracts +- `agenticlens` when Control Tower needs summarized observability or readiness + posture +- `agentic-sidecar` when Control Tower needs summarized governance or risk + posture +- `agentic-chaos` when Control Tower needs summarized experiment or resilience + posture +- `deep-agentic-core-mcp` when the control plane is later exposed to AI + operators through MCP + +### Current Roadmap Focus + +The current build focus is the v0.1 registry and discovery core. Work in this +repo should strengthen explicit registration, heartbeat handling, capability +inventory, and the read-only control surface before attempting orchestration, +bulk actions, or a rich dashboard. + +### Before You Build Here + +- Ask whether the feature is about operator control and fleet visibility; if it + is really analysis, governance, chaos execution, or MCP exposure, it may + belong in a sibling repo instead +- Keep adapters thin and contract-driven; do not copy implementation logic from + Lens, Sidecar, Chaos, or MCP into this package +- Build read-only inventory and status first; avoid jumping ahead to write-side + orchestration without the underlying control model in place + +## Status + +This repository is a **scaffold**. Package layout, docs, tests, and CI/release +workflows exist; only a very small in-memory registry/discovery/API skeleton is +implemented today. See [ROADMAP.md](ROADMAP.md) for the actual build order. + +## Build and Run + +- Install: `make install` (runs `uv sync --extra dev`) +- Test: `make test` or `make check` (lint + format + typecheck + test) +- Lint: `make lint` +- Type check: `make typecheck` +- CLI: not published yet — `[project.scripts]` is intentionally absent from + `pyproject.toml` until the CLI becomes a real supported surface + +## Code Style + +- Strict typing (mypy strict mode, Python 3.10+) +- Line length: 100 +- Ruff rules: E, F, I, UP, B, SIM, N +- One purpose per file (separation of concerns) +- Control-plane artifacts should stay compatible with ecosystem-wide contract + work once those shapes are formalized + +## Design Constraints + +These are load-bearing, not preferences — see +[ROADMAP.md](ROADMAP.md#design-constraints) for the full rationale: + +1. **Inventory before orchestration.** v0.1 should answer what exists and what + is installed before attempting remote change or fleet-wide mutation. +2. **Read-only before write-capable.** Registration, discovery, and status must + be trustworthy before configuration or operations fan out across agents. +3. **API and CLI before dashboard.** The console should sit on the same control + model, not become the hidden place where the real behavior lives. +4. **Adapters stay thin.** `adapters/` should summarize or bridge, not own + Lens, Sidecar, Chaos, or MCP behavior. +5. **Runtime agnostic means no early runtime lock-in.** Do not quietly design + the first release around one cloud, one orchestrator, or one framework. +6. **MCP comes after the control API.** AI-native access is valuable, but it + should connect to a real control plane rather than a concept-only surface. + +## Repo Map + +| Path | Purpose | Planned version | +|------|---------|------------------| +| `src/agenticops_control_tower/models/` | Shared inventory and status models | v0.1 | +| `src/agenticops_control_tower/registry/` | Agent registration, heartbeat, and inventory state | v0.1 | +| `src/agenticops_control_tower/discovery/` | Capability discovery and normalization | v0.1 | +| `src/agenticops_control_tower/api/` | Unified read-only control-plane API surface | v0.1 | +| `src/agenticops_control_tower/cli/` | Operator CLI | v0.2 | +| `src/agenticops_control_tower/console/` | AgenticOps Console / dashboard | v0.3 | +| `src/agenticops_control_tower/config/` | Central configuration models and safe write paths | v0.4 | +| `src/agenticops_control_tower/adapters/` | Thin ecosystem adapters to sibling projects and MCP | v0.5+ | +| `examples/` | Sample registration and capability payloads | ongoing | +| `tests/` | Pytest test suite | ongoing | +| `Makefile` | Local dev automation | — | + +Full architecture and build order: [ROADMAP.md](ROADMAP.md). + +## Entry Points (planned) + +- Python API: read-only control surface through `api/` +- CLI: `deepagent ...` (planned in v0.2) +- Console: AgenticOps Console (planned in v0.3) + +## Package Boundaries + +- This package should stay **standalone** — `pip install + agenticops-control-tower` must work without requiring any other + DeepAgentLabs package +- Sibling integrations must remain optional and degrade honestly when the + sibling package is unavailable +- `api/` may depend on `registry/` and `discovery/`; the reverse should not be + true +- `models/` must not import from adapters or UI layers +- `console/` should consume the same underlying control model as `api/` and + `cli/`, not invent a parallel one + +## Adding a New Control-Plane Surface + +1. Confirm the feature belongs to operator control, inventory, configuration, + or fleet visibility rather than to a sibling runtime +2. Add or update the shared model first if the feature changes inventory or + status meaning +3. Add tests covering the read path before adding any write path +4. Update `README.md` and `ROADMAP.md` if the feature changes milestone scope + +## Feature Completion Expectations + +- Every behavior change must include tests +- User-facing features must include or update examples in `README.md`, + `examples/`, or docs +- When a roadmap item or milestone meaningfully changes status, update + `README.md` and `ROADMAP.md` in the same change +- If that milestone or release changes the public ecosystem story, also update + `/home/pramodbn27/PyPi Projects/.github/profile/README.md` and, when + relevant, `/home/pramodbn27/PyPi Projects/.github/profile/ROADMAP.md` +- When work is packaged as a release-ready change, also update + `pyproject.toml`, `src/agenticops_control_tower/__init__.py`, and + `CHANGELOG.md` + +## Pre-push Checklist + +Run `make check` before every push. It runs: lint -> format-check -> typecheck +-> test. + +## Release + +1. Bump version in `pyproject.toml`, `src/agenticops_control_tower/__init__.py`, and `CHANGELOG.md` +2. Commit: `git commit -am "release: vX.Y.Z"` +3. Tag: create an annotated `vX.Y.Z` tag and use the latest `CHANGELOG.md` + release section as the tag description +4. Push: `git push origin main --tags` + +The `release-pypi.yml` workflow triggers on tag push or a published GitHub +release and publishes to PyPI via Trusted Publishing once the `pypi` GitHub +Environment and PyPI Trusted Publisher configuration exist. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f10fdbd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## 0.0.1 + +- Initial repository scaffold +- Concept-stage README and roadmap +- Package layout, tests, and CI/release workflows + diff --git a/CI.md b/CI.md new file mode 100644 index 0000000..5b8e40b --- /dev/null +++ b/CI.md @@ -0,0 +1,13 @@ +# CI + +The scaffold CI currently checks: + +- installability with `uv` +- linting with `ruff` +- formatting with `ruff format --check` +- type checking with `mypy` +- tests with `pytest` +- package build integrity with `python -m build` and `twine check` + +The workflows live under [`.github/workflows/`](.github/workflows/). + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..0071c8a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing + +This repository is still in the scaffold stage. + +For now, contributions should stay focused on: + +- clarifying the control-plane boundary +- tightening the registration and discovery model +- building narrow, testable implementation slices from [ROADMAP.md](ROADMAP.md) + +Before opening a large feature PR, prefer aligning the milestone and package +boundary first in an issue or design note. + +## Local development + +```bash +make install +make check +``` + +## Scope discipline + +`agenticops-control-tower` should own operator-facing control-plane behavior. +If a change mostly adds observability logic, governance logic, chaos logic, or +MCP logic, it may belong in a sibling repository instead. + diff --git a/DeepAgent-Control-Tower-Concept.md b/DeepAgent-Control-Tower-Concept.md new file mode 100644 index 0000000..6ff8831 --- /dev/null +++ b/DeepAgent-Control-Tower-Concept.md @@ -0,0 +1,990 @@ +# DeepAgent Control Tower + +> **A runtime-agnostic, framework-agnostic unified control plane for Agentic AI operations.** + +**Product:** DeepAgent Control Tower +**Control Tower PyPI:** `agenticops-control-tower` + +```bash +pip install agenticops-control-tower +``` + +--- + +# 1. Overview + +**DeepAgent Control Tower** is the centralized **Control Room and unified management plane** for the DeepAgentLabs open-source ecosystem. + +DeepAgentLabs provides modular capabilities for operating Agentic AI systems: + +- **AgenticLens — OBSERVE** +- **Agentic-Sidecar — GOVERN** +- **Agentic-Chaos — TEST** +- **Agentic MCP — CONNECT** +- **DeepAgent Control Tower — OPERATE** + +Each project remains independently usable. + +As developers begin using multiple DeepAgentLabs components across multiple AI agents and environments, however, they need one place to answer: + +- What AI agents are running? +- Where are they running? +- Which DeepAgentLabs PyPI packages/capabilities are being used? +- Which versions are deployed? +- Are the agents and capabilities healthy? +- What is AgenticLens observing? +- What decisions and risks is Agentic-Sidecar identifying? +- What Chaos experiments are configured or running? +- What configuration is active? +- Can capabilities be enabled, disabled, or reconfigured centrally? +- Can operations be performed across one agent or many agents? +- Can an AI agent interact with all these capabilities through MCP? + +**DeepAgent Control Tower provides this missing Control Room.** + +--- + +# 2. The Missing Layer — Control Room + +Without Control Tower: + +```text +AI Agent +│ +├── AgenticLens +├── Agentic-Sidecar +├── Agentic-Chaos +└── Agentic MCP +``` + +Each component performs its own specialized function. + +But there is no centralized operational layer answering: + +> **What is deployed, where is it running, what is happening, and how do I manage everything from one place?** + +DeepAgent Control Tower fills this gap. + +```text + ┌─────────────────────────────────┐ + │ DEEPAGENT │ + │ CONTROL TOWER │ + │ │ + │ AgenticOps Console │ + │ Agent Registry │ + │ Capability Discovery │ + │ Configuration │ + │ Unified Control API │ + │ CLI │ + └────────────────┬────────────────┘ + │ + Manage / Configure / Control + │ + ┌──────────────────┼──────────────────┐ + │ │ │ + ▼ ▼ ▼ + AgenticLens Agentic-Sidecar Agentic-Chaos + OBSERVE GOVERN TEST +``` + +DeepAgent Control Tower is therefore **not merely a dashboard**. + +The dashboard is only one interface to the underlying Control Tower. + +--- + +# 3. DeepAgent Control Tower Components + +```text +DeepAgent Control Tower +│ +├── AgenticOps Console +│ └── Web Dashboard / Control Room +│ +├── Control API +│ └── Unified programmatic interface +│ +├── Agent Registry +│ └── Inventory of registered AI agents +│ +├── Capability Discovery +│ └── Discover DeepAgentLabs capabilities/packages +│ +├── Configuration +│ └── Central configuration management +│ +└── CLI + └── Human/operator command-line interface +``` + +These components together form the **Control Tower**. + +--- + +# 4. AgenticOps Console — Web Dashboard + +The **AgenticOps Console** is the graphical interface to DeepAgent Control Tower. + +It provides a centralized view across registered AI agents and DeepAgentLabs capabilities. + +Example: + +```text +┌────────────────────────────────────────────────────┐ +│ DEEPAGENT CONTROL TOWER │ +├────────────────────────────────────────────────────┤ +│ │ +│ Agents 17 │ +│ Healthy 15 │ +│ Needs Attention 2 │ +│ │ +│ Capabilities │ +│ │ +│ AgenticLens 14 │ +│ Agentic-Sidecar 9 │ +│ Agentic-Chaos 6 │ +│ Agentic MCP 11 │ +│ │ +├────────────────────────────────────────────────────┤ +│ payment-agent │ +│ │ +│ Runtime AWS Lambda │ +│ Status ● Healthy │ +│ │ +│ AgenticLens ● Enabled │ +│ Agentic-Sidecar ● Enabled │ +│ Agentic-Chaos ○ Disabled │ +│ Agentic MCP ● Enabled │ +│ │ +│ Evaluation 98.2% │ +│ Risk Events 7 │ +│ Recent Failures 3 │ +│ │ +│ [Lens] [Sidecar] [Chaos] [Config] [Operations] │ +└────────────────────────────────────────────────────┘ +``` + +The Console should eventually provide: + +- Agent inventory +- Agent health +- Runtime information +- Capability inventory +- Package versions +- AgenticLens insights +- Agentic-Sidecar decisions and risks +- Agentic-Chaos experiments +- Configuration +- Operational actions +- Alerts and warnings +- Cross-agent visibility + +--- + +# 5. Agent Registry + +Control Tower maintains a centralized inventory of known AI agents. + +For example: + +```text +Agent Registry + +payment-agent +customer-support-agent +research-agent +security-agent +coding-agent +``` + +Each registered agent can contain metadata such as: + +```text +Agent +├── Agent ID +├── Name +├── Environment +├── Runtime +├── Framework +├── Status +├── Capabilities +├── Package Versions +└── Last Seen +``` + +Example: + +```text +payment-agent + +Environment production +Runtime AWS Lambda +Framework LangGraph +Status Healthy + +Capabilities +├── AgenticLens 0.8.1 +├── Agentic-Sidecar 0.4.0 +└── Agentic MCP 0.3.0 +``` + +--- + +# 6. Capability Discovery + +One of the major responsibilities of Control Tower is **discovering what DeepAgentLabs capabilities are being used by each agent**. + +Developers should ideally not have to manually maintain this inventory. + +For example, the individual packages can identify themselves through a common capability contract: + +```json +{ + "agent_id": "payment-agent", + "environment": "production", + "runtime": "aws-lambda", + "capabilities": { + "agenticlens": "0.8.1", + "agentic-sidecar": "0.4.0", + "agentic-chaos": "0.5.2", + "agentic-mcp": "0.3.0" + } +} +``` + +Control Tower can then automatically understand: + +```text +payment-agent + +✓ AgenticLens +✓ Agentic-Sidecar +✓ Agentic-Chaos +✓ Agentic MCP +``` + +Capability Discovery should eventually identify: + +- Which DeepAgentLabs capabilities are present +- Package versions +- Capability status +- Supported features +- Runtime/environment +- Framework +- Last heartbeat/communication +- Compatibility information + +--- + +# 7. Configuration Management + +Control Tower provides centralized configuration management for supported DeepAgentLabs capabilities. + +Example: + +```text +payment-agent +──────────────────────────── + +AgenticLens + +Tracing ON +Evaluation ON +Sampling 50% + +Agentic-Sidecar + +Supervision ON +Risk Threshold HIGH +Human Approval ON + +Agentic-Chaos + +Chaos Testing OFF +Production Experiments DISABLED +``` + +The objective is: + +> **Manage supported configuration across one or many agents without independently configuring every deployed component.** + +--- + +# 8. Unified Control API + +Control Tower exposes a **Unified Control API**. + +Instead of external systems needing to understand every individual package independently, Control Tower provides one operational interface. + +Conceptually: + +```text + Unified Control API + │ + ┌────────────┼────────────┐ + │ │ │ + ▼ ▼ ▼ + Lens Sidecar Chaos +``` + +Possible operations include: + +```text +agents.list() +agents.get() +agents.health() + +capabilities.list() +capabilities.status() + +lens.get_traces() +lens.get_evaluations() + +sidecar.get_decisions() +sidecar.get_risks() + +chaos.list_experiments() +chaos.run_experiment() + +config.get() +config.update() +``` + +The exact API contract can evolve independently from the high-level architecture. + +--- + +# 9. CLI + +Control Tower can expose a CLI for developers and operators. + +For example: + +```bash +deepagent agents list +``` + +```bash +deepagent status payment-agent +``` + +```bash +deepagent capabilities payment-agent +``` + +```bash +deepagent config get payment-agent +``` + +```bash +deepagent lens status payment-agent +``` + +```bash +deepagent sidecar status payment-agent +``` + +```bash +deepagent chaos experiments payment-agent +``` + +The CLI and AgenticOps Console should operate against the same underlying Control Tower APIs. + +--- + +# 10. Agentic MCP — Independent Universal Connector + +**Agentic MCP is an independent DeepAgentLabs PyPI project.** + +It is **not a subcomponent of DeepAgent Control Tower**. + +Its purpose is to provide **AI-native access to DeepAgentLabs capabilities through MCP**. + +The core architectural principle is: + +> **Agentic MCP can connect directly to individual DeepAgentLabs PyPI capabilities AND to DeepAgent Control Tower.** + +Therefore: + +```text +Agentic MCP +│ +├── AgenticLens Connector +├── Agentic-Sidecar Connector +├── Agentic-Chaos Connector +└── DeepAgent Control Tower Connector +``` + +This makes Agentic MCP the **CONNECT layer** across the entire DeepAgentLabs ecosystem. + +--- + +# 11. MCP Direct Mode + +Control Tower is **not required** for MCP. + +For example, a developer may only use AgenticLens: + +```text +AI Agent / MCP Client + │ + ▼ + Agentic MCP + │ + ▼ + AgenticLens +``` + +Or: + +```text +AI Agent / MCP Client + │ + ▼ + Agentic MCP + │ + ▼ + Agentic-Chaos +``` + +Or MCP could expose multiple installed capabilities: + +```text + Agentic MCP + │ + ┌──────────┼──────────┐ + ▼ ▼ ▼ + Lens Sidecar Chaos +``` + +This preserves the modular architecture. + +--- + +# 12. MCP Control Tower Mode + +When DeepAgent Control Tower is present, MCP can connect to it as another capability. + +```text +AI / Copilot / Agent + │ + ▼ + Agentic MCP + │ + ▼ +DeepAgent Control Tower + │ + ┌────┼─────┐ + ▼ ▼ ▼ + Lens Sidecar Chaos +``` + +An authorized AI agent could potentially request: + +> List all registered agents. + +> Which agents are unhealthy? + +> Which agents have Agentic-Chaos installed? + +> Show all agents using an outdated AgenticLens version. + +> Show the recent high-risk decisions from Agentic-Sidecar. + +> Enable enhanced tracing for payment-agent. + +> Run an approved API-timeout Chaos experiment against payment-agent in staging. + +MCP translates AI-native interaction into operations against the Control Tower's Unified Control API. + +--- + +# 13. MCP Can Access Every DeepAgentLabs PyPI + +The intended relationship is: + +```text + AGENTIC MCP + CONNECT + │ + ┌─────────────────────┼──────────────────────┐ + │ │ │ + ▼ ▼ ▼ + AgenticLens Agentic-Sidecar Agentic-Chaos + │ │ │ + │ │ │ + └─────────────────────┼──────────────────────┘ + │ + ▼ + DeepAgent Control Tower +``` + +Therefore MCP can provide AI-native access to: + +```text +AgenticLens ✓ +Agentic-Sidecar ✓ +Agentic-Chaos ✓ +DeepAgent Control Tower ✓ +``` + +Future DeepAgentLabs capabilities can follow the same connector model. + +--- + +# 14. Independence Between MCP and Control Tower + +A critical architectural principle is: + +> **Agentic MCP does not require DeepAgent Control Tower.** + +And: + +> **DeepAgent Control Tower does not require Agentic MCP.** + +They are independently usable components. + +```text +Control Tower without MCP + +Human + │ + ├── AgenticOps Console + │ + ├── CLI + │ + └── Control API + │ + ▼ + Control Tower +``` + +And: + +```text +MCP without Control Tower + +AI Agent + │ + ▼ +Agentic MCP + │ + ▼ +AgenticLens / Sidecar / Chaos +``` + +When combined: + +```text +AI Agent + │ + ▼ +Agentic MCP + │ + ▼ +Control Tower + │ + ├── Lens + ├── Sidecar + └── Chaos +``` + +This provides maximum flexibility. + +--- + +# 15. Human and AI Interfaces + +The architecture therefore supports two primary types of operators. + +## Human Operators + +Humans interact through: + +```text +AgenticOps Console +CLI +Control API +``` + +## AI Operators + +AI systems interact through: + +```text +Agentic MCP +``` + +Conceptually: + +```text + HUMAN AI + │ │ + ┌─────────┼─────────┐ │ + ▼ ▼ ▼ ▼ + Console CLI API Agentic MCP + │ │ │ │ + └─────────┴────┬────┘ │ + │ │ + ▼ ▼ + DeepAgent Control Tower + │ + ┌───────────┼───────────┐ + ▼ ▼ ▼ + Lens Sidecar Chaos +``` + +--- + +# 16. Runtime Agnostic + +DeepAgent Control Tower must not assume where an AI agent runs. + +Supported environments can eventually include: + +```text +AWS Lambda +AWS AgentCore +Amazon ECS +Amazon EKS +Azure Functions +Azure Container Apps +Google Cloud Run +Kubernetes +VMs +Local Python +On-premises +Serverless +Custom runtimes +``` + +For example: + +```text + AWS Lambda AgentCore Kubernetes Local + │ │ │ │ + ▼ ▼ ▼ ▼ + Agent A Agent B Agent C Agent D + │ │ │ │ + └────────────────┴────────┬────────┴────────────────┘ + │ + ▼ + DeepAgent Control Tower +``` + +The architecture does not require Docker or Kubernetes. + +Docker, Helm, cloud services, or other packaging/deployment mechanisms can be supported as optional deployment choices. + +> **Deployment mechanism is an implementation choice, not an architectural dependency.** + +--- + +# 17. Framework Agnostic + +The same architecture should work across Agentic AI frameworks. + +Potential integrations include: + +- LangGraph +- CrewAI +- AutoGen +- OpenAI Agents SDK +- Microsoft Agent Framework +- AWS AgentCore workloads +- MCP-based agents +- Custom Python agents +- Future agent frameworks + +The Control Tower operates on the DeepAgentLabs capability model rather than requiring one specific agent framework. + +--- + +# 18. Modular Installation + +Every component remains independently installable. + +For example: + +```bash +pip install agenticlens +``` + +or: + +```bash +pip install agentic-sidecar +``` + +or: + +```bash +pip install agentic-chaos +``` + +or the existing Agentic MCP package. + +When centralized management is needed: + +```bash +pip install agenticops-control-tower +``` + +The ecosystem philosophy is: + +> **Start with the capability you need. Add others when required. Use DeepAgent Control Tower when you need centralized operations.** + +--- + +# 19. Relationship with AgenticOps Specification + +The **AgenticOps Specification** can provide the common conceptual and interoperability foundation underneath the ecosystem. + +Potential standardized concepts include: + +- Agent identity +- Agent capabilities +- Runs +- Sessions +- Intent +- Plans +- Decisions +- Tool calls +- MCP interactions +- Evaluations +- Risk events +- Faults +- Experiments +- Evidence +- Outcomes +- Operational states +- Capability discovery +- Configuration contracts + +Conceptually: + +```text + DeepAgent Control Tower + │ + ┌────────────────┼────────────────┐ + ▼ ▼ ▼ + AgenticLens Agentic-Sidecar Agentic-Chaos + ▲ ▲ ▲ + └────────────────┼────────────────┘ + │ + Agentic MCP + │ + ▼ + AgenticOps Specification + Common Operational Model +``` + +--- + +# 20. Complete Architecture + +```text + DEEPAGENTLABS + + │ + ▼ + + ┌─────────────────────────────┐ + │ DEEPAGENT CONTROL TOWER │ + │ │ + │ OPERATE │ + │ │ + │ AgenticOps Console │ + │ Agent Registry │ + │ Capability Discovery │ + │ Configuration │ + │ Unified Control API │ + │ CLI │ + └──────────────┬──────────────┘ + │ + Manage / Control + │ + ┌──────────────────┼──────────────────┐ + │ │ │ + ▼ ▼ ▼ + ┌───────────┐ ┌─────────────┐ ┌─────────────┐ + │AgenticLens│ │ Agentic │ │ Agentic │ + │ │ │ Sidecar │ │ Chaos │ + │ OBSERVE │ │ GOVERN │ │ TEST │ + └───────────┘ └─────────────┘ └─────────────┘ + ▲ ▲ ▲ + │ │ │ + └──────────────────┼──────────────────┘ + │ + ┌─────┴─────┐ + │ Agentic │ + │ MCP │ + │ │ + │ CONNECT │ + └─────┬─────┘ + │ + │ Also connects directly to + ▼ + DeepAgent Control Tower + +──────────────────────────────────────────────────────────────── + + AgenticOps Spec + + Common contracts and semantics + + STANDARDIZE +``` + +The important architectural distinction is: + +```text +CONTROL TOWER = OPERATE + +MCP = CONNECT + +LENS = OBSERVE + +SIDECAR = GOVERN + +CHAOS = TEST + +AGENTICOPS = STANDARDIZE +``` + +--- + +# 21. Control Tower Internal Architecture + +At the highest level: + +```text + ┌────────────────────────────┐ + │ DEEPAGENT │ + │ CONTROL TOWER │ + │ │ + │ AgenticOps Console │ + │ Agent Registry │ + │ Capability Discovery │ + │ Configuration │ + │ Unified Control API │ + │ CLI │ + └─────────────┬──────────────┘ + │ + Unified Operations + │ + ┌──────────────────┼──────────────────┐ + │ │ │ + ▼ ▼ ▼ + AgenticLens Agentic-Sidecar Agentic-Chaos +``` + +This is the central **Control Room** for DeepAgentLabs. + +--- + +# 22. Design Principles + +## 1. Runtime Agnostic + +No dependency on Kubernetes, Docker, Lambda, AgentCore, or any particular runtime. + +## 2. Framework Agnostic + +No dependency on one Agentic AI framework. + +## 3. Modular + +Every DeepAgentLabs project works independently. + +## 4. Control Tower Optional + +Using AgenticLens, Sidecar, Chaos, or MCP does not require Control Tower. + +## 5. MCP Independent + +Agentic MCP remains an independent PyPI project. + +## 6. Universal MCP Connectivity + +MCP can provide AI-native access to individual DeepAgentLabs capabilities as well as DeepAgent Control Tower. + +## 7. Automatic Capability Discovery + +Control Tower should automatically discover available DeepAgentLabs capabilities wherever technically possible. + +## 8. Unified Control + +Control Tower provides one operational interface across multiple agents and capabilities. + +## 9. Human + AI Operable + +Humans operate through Console, CLI, and API. + +AI systems operate through MCP. + +## 10. Safe by Default + +Sensitive operations should support authorization, auditability, policy boundaries, and human approval. + +## 11. Open Source First + +The ecosystem should remain useful without requiring a proprietary hosted platform. + +--- + +# 23. DeepAgentLabs Product Model + +The entire ecosystem can now be communicated in five words: + +### OBSERVE + +**AgenticLens** + +Understand what agents are doing. + +### GOVERN + +**Agentic-Sidecar** + +Supervise decisions, intent, risk, and policy. + +### TEST + +**Agentic-Chaos** + +Validate how agents behave under failure. + +### CONNECT + +**Agentic MCP** + +Provide AI-native access to every DeepAgentLabs capability, including Control Tower. + +### OPERATE + +**DeepAgent Control Tower** + +Discover, configure, manage, and control the ecosystem from one place. + +And underneath everything: + +### STANDARDIZE + +**AgenticOps Specification** + +Provide common operational concepts, contracts, and semantics. + +--- + +# 24. Final Positioning + +> **DeepAgent Control Tower is the open-source, runtime- and framework-agnostic Control Room for Agentic AI operations, providing centralized agent discovery, capability discovery, configuration, visibility, and operational control across the DeepAgentLabs ecosystem.** + +Agentic MCP complements it by providing the AI-native connectivity layer: + +> **Agentic MCP provides a universal MCP interface to individual DeepAgentLabs capabilities—including AgenticLens, Agentic-Sidecar, Agentic-Chaos—and to the unified DeepAgent Control Tower.** + +Together, the ecosystem provides: + +> **Observe. Govern. Test. Connect. Operate. Standardize.** \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..71b430a --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2026 agenticops-control-tower Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e94c511 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +.DEFAULT_GOAL := help + +.PHONY: help install lint format format-check typecheck test test-cov clean build check + +help: ## Show this help + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \ + awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' + +install: ## Install dependencies (dev extras) + uv sync --extra dev + +lint: ## Run ruff linter + uv run ruff check src tests + +format: ## Auto-format code + uv run ruff format src tests + +format-check: ## Check formatting without changes + uv run ruff format --check src tests + +typecheck: ## Run mypy type checking + uv run mypy + +test: ## Run tests + uv run pytest + +test-cov: ## Run tests with coverage + uv run pytest --cov --cov-report=term-missing + +clean: ## Remove build artifacts + rm -rf dist/ build/ *.egg-info src/*.egg-info .mypy_cache .pytest_cache .ruff_cache + +build: ## Build package distributions + uv run python -m build + +check: lint format-check typecheck test ## Run all quality gates + diff --git a/README.md b/README.md index a0ba571..72b0684 100644 --- a/README.md +++ b/README.md @@ -1 +1,239 @@ -# agenticops-control-tower \ No newline at end of file +# agenticops-control-tower + +**A unified control plane and operations console for the DeepAgentLabs ecosystem.** + +> AgenticLens observes. Agentic Sidecar governs. Agentic Chaos tests. Agentic +> MCP connects. Control Tower operates. + +## Status + +**Concept / pre-implementation.** This repository currently contains the +architecture proposal ([`DeepAgent Control Tower End-to-End Concept.md`](DeepAgent%20Control%20Tower%20End-to-End%20Concept.md)), +this README, and the build plan in [ROADMAP.md](ROADMAP.md). + +There is **no package code, no PyPI release, no API server, no CLI, and no web +console yet**. The point of the project today is to define the control-plane +shape clearly enough that implementation can start in a narrow, believable +order. + +## Contents + +- [Why this exists](#why-this-exists) +- [What Control Tower is](#what-control-tower-is) +- [What it is not](#what-it-is-not) +- [Architecture](#architecture) +- [Control Tower surfaces](#control-tower-surfaces) +- [Human operators and AI operators](#human-operators-and-ai-operators) +- [Runtime and framework position](#runtime-and-framework-position) +- [The DeepAgentLabs ecosystem](#the-deepagentlabs-ecosystem) +- [Initial scope](#initial-scope) +- [Roadmap](#roadmap) + +## Why this exists + +The DeepAgentLabs projects each answer a different operational question: + +- **AgenticLens** asks: what happened, why did it happen, and what should I fix? +- **Agentic Sidecar** asks: should this action happen right now, given the + user's intent and current risk? +- **Agentic Chaos** asks: what breaks under stress, failure, and silent + degradation? +- **Agentic MCP** asks: how do hosts and agents access these capabilities + through one MCP-native surface? + +What is still missing is the layer above them: + +> What is deployed, where is it running, which capabilities are enabled, what +> is unhealthy, and how do I operate all of it from one place? + +That missing layer is the job of `agenticops-control-tower`. + +## What Control Tower is + +Control Tower is intended to be the **runtime-agnostic, framework-agnostic +operations layer** for teams running multiple agents and multiple +DeepAgentLabs capabilities. + +At a high level, it should eventually provide: + +- a central agent registry +- capability discovery across agents and environments +- health and status visibility +- centralized configuration for supported capabilities +- a unified control API +- a human CLI +- a web console for operators + +The key distinction is that Control Tower is **not just a dashboard**. The +dashboard is only one interface to the underlying control plane. + +## What it is not + +- **Not a replacement for AgenticLens.** Control Tower may surface Lens + insights, but Lens remains the observability and evaluation engine. +- **Not a replacement for Agentic Sidecar.** Control Tower may surface + Sidecar decisions and governance posture, but Sidecar remains the + decision-time supervision layer. +- **Not a replacement for Agentic Chaos.** Control Tower may orchestrate or + summarize chaos posture, but Chaos remains the resilience-testing engine. +- **Not the MCP layer itself.** Agentic MCP remains an independent package + and should be able to connect both to individual DeepAgentLabs capabilities + and to Control Tower. +- **Not tied to one runtime or one framework.** The control plane should sit + above LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, AWS AgentCore-style + workloads, MCP-native agents, and custom Python systems rather than + assuming one execution model. +- **Not implemented yet.** The architecture in the concept doc is broader + than what a first real release should attempt. See [ROADMAP.md](ROADMAP.md) + for the narrowed build order. + +## Architecture + +The ecosystem boundary should stay crisp: + +```text +Control Tower = OPERATE +Agentic MCP = CONNECT +AgenticLens = OBSERVE +Agentic Sidecar = GOVERN +Agentic Chaos = TEST +AI Operations Specification = STANDARDIZE +``` + +Conceptually: + +```text + Human operators AI operators + | | + Console / CLI / API Agentic MCP + | | + +-----------+-----------+ + | + v + DeepAgent Control Tower + | + +------------------+------------------+ + | | | + v v v + AgenticLens Agentic Sidecar Agentic Chaos +``` + +Control Tower's role is to centralize operations across agents and +capabilities, not to absorb the implementation logic of the sibling projects. + +## Control Tower surfaces + +The concept doc points to five main product surfaces: + +- **Agent Registry**: inventory of known agents, runtimes, frameworks, + environments, capability versions, and last-seen status +- **Capability Discovery**: detect which DeepAgentLabs packages and features + are present on each agent wherever automatic discovery is technically + feasible +- **Configuration**: centralized configuration and policy updates for + supported capabilities +- **Unified Control API**: one programmatic interface over inventory, health, + capability status, and supported operations +- **AgenticOps Console**: the human-facing dashboard over the same control + plane used by the API and CLI + +The CLI should be a first-class interface, not an afterthought. The same is +true for AI-facing operation through Agentic MCP once the underlying control +API exists. + +## Human operators and AI operators + +This project is unusual in that it has two equally important operator models: + +- **Humans** should be able to use a console, CLI, or API to inspect and + operate agents across environments. +- **AI systems** should be able to use Agentic MCP to inspect and operate the + same control plane through an MCP-native interface. + +That separation matters: + +- Control Tower does **not** require MCP +- MCP does **not** require Control Tower +- when used together, MCP becomes the AI-native interface to the control + plane + +## Runtime and framework position + +Control Tower should be: + +- **runtime agnostic**: local Python, containers, VMs, Kubernetes, + serverless, cloud-specific runtimes, and on-prem systems are all valid + targets +- **framework agnostic**: LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, + custom harnesses, MCP-based agents, and future frameworks should all fit + the model +- **modular**: teams should be able to adopt a single DeepAgentLabs + capability without adopting the entire stack + +That means deployment packaging is an implementation choice, not an +architectural dependency. + +## The DeepAgentLabs ecosystem + +Control Tower only makes sense if the package boundaries stay clear: + +| Project | Role | +| --- | --- | +| `agenticlens` | Observe | +| `agentic-sidecar` | Govern | +| `agentic-chaos` | Test | +| `deep-agentic-core-mcp` | Connect | +| `ai-operations-spec` | Standardize | +| `agenticops-control-tower` | Operate | + +- **AgenticLens** remains package-first observability, evaluation, and + operational intelligence +- **Agentic Sidecar** remains package-first supervision and governance +- **Agentic Chaos** remains package-first resilience and fault injection +- **Agentic MCP** remains the MCP-native access layer +- **AI Operations Specification** remains the shared operational contract +- **Control Tower** becomes the centralized operate/manage layer across them + +This repository should therefore stay focused on: + +- inventory and registry concerns +- control-plane APIs +- capability discovery contracts +- health and readiness visibility +- centralized operations and configuration +- multi-agent, multi-environment control-room workflows + +It should not quietly turn into a duplicate implementation of the sibling +projects. + +## Initial scope + +The concept doc describes a very broad end state. A good first implementation +needs to be much narrower. + +The first usable version should likely prove four things only: + +1. agents can register and heartbeat +2. the system can discover installed DeepAgentLabs capabilities and versions +3. operators can inspect that inventory through a simple API and CLI +4. the same inventory can be surfaced later in a console without changing the + underlying control model + +That is enough to validate the control-plane idea without pretending the full +dashboard, configuration orchestration, and cross-agent operations engine +already exist. + +## Roadmap + +The build plan is in [ROADMAP.md](ROADMAP.md). In short, the intended order +should be: + +- start with a narrow registry and discovery core +- add a real control API and CLI before building the dashboard +- surface Lens, Sidecar, and Chaos data gradually rather than simulating a + complete integration layer +- add MCP connectivity to Control Tower after the underlying control surfaces + are real + +If you want the full architectural reasoning behind those choices, read the +concept doc first and the roadmap second. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..f62bc9e --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,368 @@ +# agenticops-control-tower — Roadmap & Architecture + +## Release Status + +- **v0.1** 🚧 Planned — Registry, Heartbeats, Capability Discovery, Read-Only API +- **v0.2** 🚧 Planned — CLI, Status Views, Health Rollups, Version Inventory +- **v0.3** 🚧 Planned — AgenticOps Console (read-only dashboard) +- **v0.4** 🚧 Planned — Configuration Model and Controlled Write Operations +- **v0.5** 🚧 Planned — Lens, Sidecar, and Chaos Surface Integration +- **v0.6** 🚧 Planned — Agentic MCP Connector for Control Tower +- **v0.7** 🚧 Planned — Multi-Agent Operations and Bulk Actions +- **v0.8** 🚧 Planned — Alerts, Audit Trails, and Incident Views +- **v1.0** 🚧 Planned — Stable Control Plane and Published Capability Contract + +Nothing has shipped yet. This repository currently contains the concept +document, this roadmap, and the README only. + +## Design Constraints + +These should shape the build order from the start, not be rediscovered later. + +1. **Inventory before orchestration.** The first release should answer + "what exists and what is installed?" before attempting "change it + remotely." A control plane without trusted inventory is theater. +2. **Read-only before write-capable.** Cross-agent configuration and + operations are the highest-risk part of the vision. Prove registration, + discovery, and status first. +3. **API and CLI before dashboard.** The web console should sit on top of the + same control model, not become the place where the actual behavior lives. +4. **Capability adapters should stay thin.** Control Tower should reuse + sibling project contracts and metadata rather than re-implement Lens, + Sidecar, or Chaos logic locally. +5. **Runtime-agnostic means avoiding runtime assumptions in v0.1.** Do not + build the first version around Kubernetes-specific or cloud-specific + registration mechanics. +6. **MCP is downstream of the control API.** Agentic MCP integration is + valuable, but only after there is a real control-plane surface to expose. +7. **Automatic discovery where possible, explicit registration where + necessary.** The architecture should prefer discovery, but not block the + product on perfect autodetection across every environment. + +## Cross-Project Dependencies + +`agenticops-control-tower` is the ecosystem control plane, so its roadmap is +mostly about coordinating with sibling projects without absorbing them. + +- `agenticlens` + Coordinate with: how Control Tower reads summarized observability, + evaluation, and readiness signals without replacing Lens as the engine. +- `agentic-sidecar` + Coordinate with: how governance posture, decision summaries, and risk + signals are surfaced centrally once Sidecar exposes stable runtime output. +- `agentic-chaos` + Coordinate with: how experiment inventory, last-run status, and resilience + posture are summarized in the control plane once Chaos artifacts stabilize. +- `mcp-server` (`deep-agentic-core-mcp`) + Validate in: a future MCP-facing path for AI-native operation against + Control Tower rather than only against individual sibling packages. +- `ai-operations-spec` + Coordinate with: agent identity, capability metadata, status events, + configuration contracts, and operational artifacts that should not drift + away from the shared ecosystem model. + +For roadmap planning, use these meanings consistently: + +- `Depends on`: the item cannot ship first. +- `Coordinate with`: sibling repos should be updated in the same window. +- `Validate in`: end-to-end checks should happen in another repo or adapter. + +## Definition of Done + +A roadmap item is done only when all applicable work is complete: + +- implementation is merged and usable through the intended API, CLI, or UI +- tests or fixtures cover the behavior +- operator-facing docs and examples are updated +- `README.md` and this roadmap are updated when the feature changes user + expectations or milestone status +- capability contracts and ecosystem-facing artifact shapes are documented +- sibling-project checks are recorded where relevant +- release metadata is updated when the work is part of a release-ready change + set + +--- + +## Architecture + +Control Tower should become the **operate/manage layer** across the +DeepAgentLabs stack: + +```text +Control Tower = OPERATE +Agentic MCP = CONNECT +AgenticLens = OBSERVE +Agentic Sidecar = GOVERN +Agentic Chaos = TEST +AI Operations Specification = STANDARDIZE +``` + +From a developer or operator perspective, the project exists to answer: + +`What agents do I have, where are they running, what DeepAgentLabs +capabilities are installed, what is unhealthy, and how do I manage all of that +through one control plane?` + +That keeps the package focused on: + +- agent registry and lifecycle visibility +- capability inventory and discovery +- control-plane API design +- centralized configuration and safe operations +- operator UX across CLI, console, and AI-facing control + +It should not become a hidden duplicate of the sibling runtimes. + +## Proposed Product Surfaces + +```text +agenticops-control-tower +├── registry/ # agent inventory, heartbeat, runtime metadata +├── discovery/ # capability detection and version inventory +├── api/ # unified control-plane API +├── config/ # central configuration model and safe write paths +├── cli/ # operator CLI +├── console/ # AgenticOps Console / dashboard +└── adapters/ # thin ecosystem adapters (Lens, Sidecar, Chaos, MCP) +``` + +This is a proposed shape, not a committed implementation layout. + +## Capability Direction + +Over time, the control plane should grow around a few clear domains: + +- inventory and registration +- health and readiness +- capability discovery +- version and compatibility visibility +- centralized configuration +- operational actions +- auditability and incident posture +- AI-native control through MCP + +Contributors should be able to ask: + +`Is this feature helping operators understand or safely control deployed +agents, or is it really work that belongs in Lens, Sidecar, Chaos, MCP, or the +spec repo instead?` + +--- + +## Build Order + +## Phase 0: Concept and Product Boundary + +Status: current + +Goals: + +- define what Control Tower is and is not +- keep boundaries clear against Lens, Sidecar, Chaos, MCP, and AIOS +- narrow the first implementation into a believable control-plane core + +Deliverables: + +- [x] architecture concept document +- [x] `README.md` +- [x] `ROADMAP.md` +- [x] implementation scaffold + +## Phase 1: Registry and Discovery Core (`v0.1`) + +Goals: + +- create a minimal agent registry +- accept explicit agent registration and heartbeats +- record runtime, framework, environment, and package metadata +- expose a read-only API for listing agents and capabilities + +Suggested initial surface: + +- `POST /agents/register` +- `POST /agents/{id}/heartbeat` +- `GET /agents` +- `GET /agents/{id}` +- `GET /capabilities` + +Success criteria: + +- operators can see which agents are known to the system +- each agent record includes capability versions and last-seen status +- the system works without assuming Kubernetes, Docker, or one framework +- example registration payloads exist for at least two runtime styles + +## Phase 2: CLI and Status Model (`v0.2`) + +Goals: + +- ship a first operator CLI +- add health rollups and version inventory summaries +- expose useful filters such as unhealthy agents or agents missing a + capability + +Suggested commands: + +- `deepagent agents list` +- `deepagent agents get ` +- `deepagent capabilities list` +- `deepagent status` + +Success criteria: + +- CLI and API share the same underlying control model +- a user can answer basic inventory questions without touching raw JSON +- health state is computed consistently rather than ad hoc per interface + +## Phase 3: Read-Only Console (`v0.3`) + +Goals: + +- ship the first AgenticOps Console +- visualize inventory, health, versions, and capability presence +- keep the dashboard read-only at first + +Success criteria: + +- the console is a thin view over the real API +- one operator can identify unhealthy or outdated agents quickly +- the dashboard does not introduce write-side behavior the API cannot do + +## Phase 4: Configuration and Safe Write Operations (`v0.4`) + +Goals: + +- define a central configuration model for supported capabilities +- add controlled write paths for safe updates +- document which configuration is authoritative versus merely mirrored + +Potential operations: + +- `config.get(agent_id)` +- `config.update(agent_id, patch)` +- `capabilities.enable(agent_id, capability)` +- `capabilities.disable(agent_id, capability)` + +Open risk: + +- configuration semantics will differ across Lens, Sidecar, and Chaos, so + v0.4 must avoid pretending one generic toggle model covers everything. + +Success criteria: + +- write operations are auditable +- partial failure behavior is explicit +- unsupported configuration surfaces degrade honestly + +## Phase 5: Ecosystem Surface Integration (`v0.5`) + +Goals: + +- surface Lens, Sidecar, and Chaos summaries in the control plane +- keep adapters thin and contract-driven +- avoid copying sibling project logic into Control Tower + +Examples: + +- Lens: evaluation summaries, health signals, recent findings +- Sidecar: decision summaries, risk posture, intervention counts +- Chaos: experiment inventory, last run, resilience posture + +Success criteria: + +- operators can inspect high-level posture centrally +- the source of truth for the underlying capability remains in the sibling + package +- integration failures degrade to "unavailable" rather than crashing the + control plane + +## Phase 6: Agentic MCP Connector (`v0.6`) + +Goals: + +- expose Control Tower to AI operators through Agentic MCP +- support AI-native inventory and status queries first +- add write-capable operations only after authorization and audit shape are + clear + +Examples: + +- list registered agents +- list unhealthy agents +- show agents with outdated package versions +- inspect recent high-risk Sidecar posture + +Success criteria: + +- MCP connects to a real control API rather than a demo surface +- read and write operations have distinct authorization boundaries +- examples exist showing MCP with and without Control Tower + +## Phase 7: Multi-Agent Operations (`v0.7`) + +Goals: + +- add bulk operations and fleet-wide targeting +- support environment-scoped and capability-scoped actions +- make operational intent explicit before write actions fan out + +Examples: + +- enable enhanced tracing for all staging agents +- find all agents missing a minimum Sidecar version +- pause a class of experiments across an environment + +Success criteria: + +- bulk actions include preview and audit paths +- rollback or reconciliation behavior is documented +- targeting semantics are deterministic + +## Phase 8: Alerts, Audit, and Incident Views (`v0.8`) + +Goals: + +- add operator-facing alerts and warnings +- add audit trails for configuration and operations +- add incident-oriented views over agent and capability posture + +Success criteria: + +- the system explains what changed, when, and by whom or by what control path +- incident views join inventory, health, and recent changes coherently + +## Phase 9: Stable Capability Contract (`v1.0`) + +Goals: + +- publish a stable capability discovery contract +- lock the core control-plane API semantics +- document supported runtime and framework integration patterns + +Success criteria: + +- at least two materially different runtimes are validated end to end +- capability metadata and status semantics are versioned +- Control Tower can be described as a stable control-plane product rather than + a concept repo + +--- + +## Open Questions + +- What is the minimum viable registration contract for agents that is still + useful across runtimes? +- Which fields should be standardized in AIOS versus left as Control Tower + implementation detail? +- How much of capability discovery can be automatic versus agent-reported? +- When configuration updates fail midway across a fleet, what is the expected + reconciliation model? +- Should the first implementation be a local-first Python service only, or + should remote deployment concerns appear in v0.1? + +## North Star + +The long-term goal is not "a nice dashboard." The goal is a **real control +room** for agentic operations: one place where human operators and AI operators +can understand, inspect, and safely operate the DeepAgentLabs ecosystem across +many agents and environments. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..a2466a7 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +This project is pre-implementation software and should not yet be treated as a +production-ready control plane. + +Until the first real write-capable release exists: + +- do not assume any authentication or authorization surface is complete +- do not expose experimental services from this repo to untrusted networks +- do not treat scaffold APIs or examples as operationally hardened + +If you discover a security issue in this repository, please report it +privately to the maintainers rather than opening a public issue. + diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..10436f5 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,15 @@ +# Architecture + +This scaffold reserves the following control-plane domains: + +- `registry/` for agent registration and heartbeat state +- `discovery/` for capability and version discovery +- `api/` for a unified control-plane surface +- `config/` for centralized configuration contracts +- `cli/` for operator workflows +- `console/` for the future AgenticOps Console +- `adapters/` for thin ecosystem integration boundaries + +See [README.md](../README.md) and [ROADMAP.md](../ROADMAP.md) for the product +boundary and milestone order. + diff --git a/examples/sample_agent_registration.json b/examples/sample_agent_registration.json new file mode 100644 index 0000000..d35169a --- /dev/null +++ b/examples/sample_agent_registration.json @@ -0,0 +1,15 @@ +{ + "agent_id": "payment-agent", + "name": "payment-agent", + "environment": "production", + "runtime": "aws-lambda", + "framework": "langgraph", + "status": "healthy", + "capabilities": { + "agenticlens": "0.8.1", + "agentic-sidecar": "0.4.0", + "agentic-chaos": "0.5.2", + "deep-agentic-core-mcp": "0.2.0" + } +} + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e0671dd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,102 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "agenticops-control-tower" +version = "0.0.1" +description = "Unified control plane and operations console for the DeepAgentLabs ecosystem." +readme = "README.md" +license = { file = "LICENSE" } +requires-python = ">=3.10" +authors = [{ name = "agenticops-control-tower Contributors" }] +keywords = ["agents", "control-plane", "operations", "observability", "governance", "chaos"] +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries :: Python Modules", +] +dependencies = [ + "pydantic>=2.0,<3", +] + +[project.optional-dependencies] +# These extras are intentionally declared before real adapters exist so the +# dependency boundaries stay visible in the scaffold. +agenticlens = [ + "agenticlens>=0.1.3", +] +agentic-sidecar = [ + "agentic-sidecar>=0.0.1", +] +agentic-chaos = [ + "agentic-chaos>=0.1", +] +deep-agentic-core-mcp = [ + "deep-agentic-core-mcp>=0.2.0", +] +dev = [ + "pytest>=8.0", + "pytest-cov>=5.0", + "ruff>=0.6", + "mypy>=1.10", + "build>=1.2", + "twine>=5.1", +] + +# Intentionally omitted for now. Add a console script once the CLI becomes a +# real supported surface instead of a scaffold placeholder. +# [project.scripts] + +[project.urls] +Homepage = "https://github.com/DeepAgentLabs/agenticops-control-tower" +Repository = "https://github.com/DeepAgentLabs/agenticops-control-tower" +Issues = "https://github.com/DeepAgentLabs/agenticops-control-tower/issues" +Changelog = "https://github.com/DeepAgentLabs/agenticops-control-tower/blob/main/CHANGELOG.md" + +[tool.hatch.build.targets.wheel] +packages = ["src/agenticops_control_tower"] + +[tool.ruff] +line-length = 100 +target-version = "py310" +src = ["src", "tests"] + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "B", "SIM", "N"] +ignore = ["B008"] + +[tool.ruff.lint.isort] +known-first-party = ["agenticops_control_tower"] + +[tool.ruff.format] +quote-style = "double" + +[tool.mypy] +python_version = "3.10" +strict = true +packages = ["agenticops_control_tower"] +mypy_path = "src" + +[[tool.mypy.overrides]] +module = [ + "agenticlens.*", + "agentic_sidecar.*", + "agentic_chaos.*", + "deep_agentic_core_mcp.*", +] +ignore_missing_imports = true + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["src"] +addopts = "-ra --cov=agenticops_control_tower --cov-report=term-missing" + +[tool.coverage.run] +source = ["src/agenticops_control_tower"] + diff --git a/src/agenticops_control_tower/__init__.py b/src/agenticops_control_tower/__init__.py new file mode 100644 index 0000000..e13b485 --- /dev/null +++ b/src/agenticops_control_tower/__init__.py @@ -0,0 +1,5 @@ +"""Scaffold package for the DeepAgentLabs control plane.""" + +__all__ = ["__version__"] + +__version__ = "0.0.1" diff --git a/src/agenticops_control_tower/adapters/__init__.py b/src/agenticops_control_tower/adapters/__init__.py new file mode 100644 index 0000000..a52995c --- /dev/null +++ b/src/agenticops_control_tower/adapters/__init__.py @@ -0,0 +1,5 @@ +"""Thin ecosystem adapter placeholders.""" + +from .catalog import ADAPTER_NAMES + +__all__ = ["ADAPTER_NAMES"] diff --git a/src/agenticops_control_tower/adapters/catalog.py b/src/agenticops_control_tower/adapters/catalog.py new file mode 100644 index 0000000..8cf1de4 --- /dev/null +++ b/src/agenticops_control_tower/adapters/catalog.py @@ -0,0 +1,8 @@ +"""Named adapter placeholders for sibling projects.""" + +ADAPTER_NAMES = ( + "agenticlens", + "agentic-sidecar", + "agentic-chaos", + "deep-agentic-core-mcp", +) diff --git a/src/agenticops_control_tower/api/__init__.py b/src/agenticops_control_tower/api/__init__.py new file mode 100644 index 0000000..ec8cf0a --- /dev/null +++ b/src/agenticops_control_tower/api/__init__.py @@ -0,0 +1,5 @@ +"""Control-plane API placeholders.""" + +from .surface import ControlTowerAPI + +__all__ = ["ControlTowerAPI"] diff --git a/src/agenticops_control_tower/api/surface.py b/src/agenticops_control_tower/api/surface.py new file mode 100644 index 0000000..6a5c2f3 --- /dev/null +++ b/src/agenticops_control_tower/api/surface.py @@ -0,0 +1,28 @@ +"""Read-only scaffold API over the registry.""" + +from __future__ import annotations + +from agenticops_control_tower.discovery import CapabilityDiscoveryService +from agenticops_control_tower.models import AgentRecord +from agenticops_control_tower.registry import AgentRegistry + + +class ControlTowerAPI: + """Small facade that mirrors the v0.1 roadmap surface.""" + + def __init__( + self, + registry: AgentRegistry, + discovery: CapabilityDiscoveryService, + ) -> None: + self._registry = registry + self._discovery = discovery + + def list_agents(self) -> list[AgentRecord]: + return self._registry.list_agents() + + def get_agent(self, agent_id: str) -> AgentRecord: + return self._registry.get(agent_id) + + def list_capabilities(self, agent_id: str) -> dict[str, str]: + return self._discovery.list_capabilities(self._registry.get(agent_id)) diff --git a/src/agenticops_control_tower/cli/__init__.py b/src/agenticops_control_tower/cli/__init__.py new file mode 100644 index 0000000..a93bd49 --- /dev/null +++ b/src/agenticops_control_tower/cli/__init__.py @@ -0,0 +1 @@ +"""CLI placeholders.""" diff --git a/src/agenticops_control_tower/cli/main.py b/src/agenticops_control_tower/cli/main.py new file mode 100644 index 0000000..f2e3d66 --- /dev/null +++ b/src/agenticops_control_tower/cli/main.py @@ -0,0 +1,11 @@ +"""Placeholder CLI entry module. + +No console script is published yet. This module exists so the scaffold already +has a stable home for future commands. +""" + + +def main() -> str: + """Return a short scaffold message for direct import-based smoke tests.""" + + return "agenticops-control-tower CLI scaffold" diff --git a/src/agenticops_control_tower/config/__init__.py b/src/agenticops_control_tower/config/__init__.py new file mode 100644 index 0000000..b84fcf0 --- /dev/null +++ b/src/agenticops_control_tower/config/__init__.py @@ -0,0 +1,5 @@ +"""Configuration placeholders.""" + +from .models import ConfigPatch, ConfigScope + +__all__ = ["ConfigPatch", "ConfigScope"] diff --git a/src/agenticops_control_tower/config/models.py b/src/agenticops_control_tower/config/models.py new file mode 100644 index 0000000..f2e13d3 --- /dev/null +++ b/src/agenticops_control_tower/config/models.py @@ -0,0 +1,19 @@ +"""Future-facing configuration models kept intentionally small.""" + +from __future__ import annotations + +from pydantic import BaseModel, Field + + +class ConfigScope(BaseModel): + """Target scope for a future centralized config operation.""" + + agent_id: str | None = None + environment: str | None = None + capability: str | None = None + + +class ConfigPatch(BaseModel): + """Opaque patch payload for the scaffold stage.""" + + values: dict[str, object] = Field(default_factory=dict) diff --git a/src/agenticops_control_tower/console/__init__.py b/src/agenticops_control_tower/console/__init__.py new file mode 100644 index 0000000..b0962ec --- /dev/null +++ b/src/agenticops_control_tower/console/__init__.py @@ -0,0 +1 @@ +"""Web console placeholders.""" diff --git a/src/agenticops_control_tower/console/app.py b/src/agenticops_control_tower/console/app.py new file mode 100644 index 0000000..bfc0682 --- /dev/null +++ b/src/agenticops_control_tower/console/app.py @@ -0,0 +1,7 @@ +"""Console placeholder surface.""" + + +def console_status() -> str: + """Return a scaffold-only status string.""" + + return "AgenticOps Console scaffold" diff --git a/src/agenticops_control_tower/discovery/__init__.py b/src/agenticops_control_tower/discovery/__init__.py new file mode 100644 index 0000000..64ce8d4 --- /dev/null +++ b/src/agenticops_control_tower/discovery/__init__.py @@ -0,0 +1,5 @@ +"""Capability discovery placeholders.""" + +from .service import CapabilityDiscoveryService + +__all__ = ["CapabilityDiscoveryService"] diff --git a/src/agenticops_control_tower/discovery/service.py b/src/agenticops_control_tower/discovery/service.py new file mode 100644 index 0000000..45a0167 --- /dev/null +++ b/src/agenticops_control_tower/discovery/service.py @@ -0,0 +1,17 @@ +"""Capability discovery scaffold. + +The real implementation will likely combine explicit agent-reported metadata +with adapter-assisted discovery. For now this module only exposes a normalized +view over an agent's reported capabilities. +""" + +from __future__ import annotations + +from agenticops_control_tower.models import AgentRecord + + +class CapabilityDiscoveryService: + """Scaffold normalization for capability inventory.""" + + def list_capabilities(self, agent: AgentRecord) -> dict[str, str]: + return dict(sorted(agent.capabilities.items())) diff --git a/src/agenticops_control_tower/models/__init__.py b/src/agenticops_control_tower/models/__init__.py new file mode 100644 index 0000000..043a9e7 --- /dev/null +++ b/src/agenticops_control_tower/models/__init__.py @@ -0,0 +1,5 @@ +"""Core models shared across scaffold modules.""" + +from .agent import AgentRecord, AgentStatus, HeartbeatPayload + +__all__ = ["AgentRecord", "AgentStatus", "HeartbeatPayload"] diff --git a/src/agenticops_control_tower/models/agent.py b/src/agenticops_control_tower/models/agent.py new file mode 100644 index 0000000..368d50b --- /dev/null +++ b/src/agenticops_control_tower/models/agent.py @@ -0,0 +1,38 @@ +"""Minimal agent inventory models for the scaffold stage.""" + +from __future__ import annotations + +from datetime import datetime, timezone +from enum import Enum + +from pydantic import BaseModel, Field + + +class AgentStatus(str, Enum): + """High-level health states for the initial registry model.""" + + HEALTHY = "healthy" + DEGRADED = "degraded" + UNHEALTHY = "unhealthy" + UNKNOWN = "unknown" + + +class HeartbeatPayload(BaseModel): + """Runtime-reported status snapshot for a registered agent.""" + + status: AgentStatus = AgentStatus.UNKNOWN + last_seen: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + capabilities: dict[str, str] = Field(default_factory=dict) + + +class AgentRecord(BaseModel): + """Inventory record for one known agent.""" + + agent_id: str + name: str + environment: str + runtime: str + framework: str + status: AgentStatus = AgentStatus.UNKNOWN + capabilities: dict[str, str] = Field(default_factory=dict) + last_seen: datetime | None = None diff --git a/src/agenticops_control_tower/registry/__init__.py b/src/agenticops_control_tower/registry/__init__.py new file mode 100644 index 0000000..1b428a8 --- /dev/null +++ b/src/agenticops_control_tower/registry/__init__.py @@ -0,0 +1,5 @@ +"""Agent registry primitives.""" + +from .service import AgentRegistry + +__all__ = ["AgentRegistry"] diff --git a/src/agenticops_control_tower/registry/service.py b/src/agenticops_control_tower/registry/service.py new file mode 100644 index 0000000..dd5ba01 --- /dev/null +++ b/src/agenticops_control_tower/registry/service.py @@ -0,0 +1,29 @@ +"""In-memory scaffold for registration and heartbeat flows.""" + +from __future__ import annotations + +from agenticops_control_tower.models import AgentRecord, HeartbeatPayload + + +class AgentRegistry: + """Very small in-memory registry to anchor the scaffold tests.""" + + def __init__(self) -> None: + self._agents: dict[str, AgentRecord] = {} + + def register(self, agent: AgentRecord) -> AgentRecord: + self._agents[agent.agent_id] = agent + return agent + + def heartbeat(self, agent_id: str, heartbeat: HeartbeatPayload) -> AgentRecord: + agent = self._agents[agent_id] + agent.status = heartbeat.status + agent.last_seen = heartbeat.last_seen + agent.capabilities = heartbeat.capabilities + return agent + + def list_agents(self) -> list[AgentRecord]: + return list(self._agents.values()) + + def get(self, agent_id: str) -> AgentRecord: + return self._agents[agent_id] diff --git a/tests/test_imports.py b/tests/test_imports.py new file mode 100644 index 0000000..c7691a9 --- /dev/null +++ b/tests/test_imports.py @@ -0,0 +1,17 @@ +from agenticops_control_tower import __version__ +from agenticops_control_tower.adapters import ADAPTER_NAMES +from agenticops_control_tower.api import ControlTowerAPI +from agenticops_control_tower.cli.main import main +from agenticops_control_tower.console.app import console_status +from agenticops_control_tower.discovery import CapabilityDiscoveryService +from agenticops_control_tower.registry import AgentRegistry + + +def test_scaffold_imports() -> None: + assert __version__ == "0.0.1" + assert "agenticlens" in ADAPTER_NAMES + assert main() == "agenticops-control-tower CLI scaffold" + assert console_status() == "AgenticOps Console scaffold" + assert AgentRegistry is not None + assert CapabilityDiscoveryService is not None + assert ControlTowerAPI is not None diff --git a/tests/test_registry.py b/tests/test_registry.py new file mode 100644 index 0000000..cc3f2a2 --- /dev/null +++ b/tests/test_registry.py @@ -0,0 +1,38 @@ +from agenticops_control_tower.api import ControlTowerAPI +from agenticops_control_tower.discovery import CapabilityDiscoveryService +from agenticops_control_tower.models import AgentRecord, AgentStatus, HeartbeatPayload +from agenticops_control_tower.registry import AgentRegistry + + +def test_registry_and_discovery_flow() -> None: + registry = AgentRegistry() + discovery = CapabilityDiscoveryService() + api = ControlTowerAPI(registry=registry, discovery=discovery) + + registry.register( + AgentRecord( + agent_id="payment-agent", + name="payment-agent", + environment="staging", + runtime="local-python", + framework="langgraph", + ) + ) + + registry.heartbeat( + "payment-agent", + HeartbeatPayload( + status=AgentStatus.HEALTHY, + capabilities={ + "agenticlens": "0.8.1", + "agentic-sidecar": "0.4.0", + }, + ), + ) + + agent = api.get_agent("payment-agent") + assert agent.status is AgentStatus.HEALTHY + assert api.list_capabilities("payment-agent") == { + "agentic-sidecar": "0.4.0", + "agenticlens": "0.8.1", + }