agentops-cockpit 0.3.0__tar.gz → 0.4.0__tar.gz
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.
- agentops_cockpit-0.4.0/A2A_GUIDE.md +58 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/PKG-INFO +22 -3
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/README.md +20 -2
- agentops_cockpit-0.4.0/public/og-image.png +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/pyproject.toml +2 -1
- agentops_cockpit-0.4.0/src/agent_ops_cockpit/ops/mcp_hub.py +80 -0
- agentops_cockpit-0.4.0/src/backend/ops/mcp_hub.py +80 -0
- agentops_cockpit-0.3.0/A2A_GUIDE.md +0 -39
- agentops_cockpit-0.3.0/src/agent_ops_cockpit/ops/mcp_hub.py +0 -35
- agentops_cockpit-0.3.0/src/backend/ops/mcp_hub.py +0 -35
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/.gitignore +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/BE_INTEGRATION_GUIDE.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/DEPLOYMENT.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/Dockerfile +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/LICENSE +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/Makefile +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/firebase.json +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/index.html +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/package.json +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/A2A_GUIDE.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/AGENT_OPS_STORY.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/BE_INTEGRATION_GUIDE.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/CLI_COMMANDS.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/DEPLOYMENT.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/DEVELOPMENT.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/GEMINI.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/GETTING_STARTED.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/README.md +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/cicd-workflow.png +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/diagrams/agentic-stack.png +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/diagrams/value-proposition.png +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/hero.png +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/App.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/A2UIRenderer.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/components/index.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/components/lit-component-example.ts +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/types.ts +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cache/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cache/semantic_cache.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cli/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cli/main.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cost_control.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/load_test.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/quality_climber.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/red_team.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/arch_review.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/cost_optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/evidence.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/frameworks.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/memory_optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/orchestrator.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/pii_scrubber.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/reliability.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/secret_scanner.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/ui_auditor.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/shadow/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/shadow/router.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/agent.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/cache/semantic_cache.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/cost_control.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/load_test.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/quality_climber.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/red_team.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/__init__.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/arch_review.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/cost_optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/evidence.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/frameworks.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/memory_optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/orchestrator.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/pii_scrubber.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/reliability.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/secret_scanner.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/ui_auditor.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/shadow/router.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_agent.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_arch_review.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_frameworks.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_optimizer.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_quality_climber.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_red_team.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_secret_scanner.py +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/FlightRecorder.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/Home.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/OpsDashboard.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/Playground.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/ThemeToggle.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/docs/DocLayout.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/docs/DocPage.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/index.css +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/knowledge/example_policy.txt +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/main.tsx +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/tsconfig.json +0 -0
- {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/vite.config.ts +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 📡 Agent-to-Agent (A2A) Transmission Standard
|
|
2
|
+
|
|
3
|
+
Building a single agent is easy. Building a **Swarm** of agents that communicate securely and efficiently is the next frontier of AgentOps. The Cockpit implements the **A2A Transmission Standard** to ensure that your "Agent Trinity" remains Well-Architected.
|
|
4
|
+
|
|
5
|
+
## 🏛️ The A2A Protocol Stack
|
|
6
|
+
|
|
7
|
+
| Layer | Responsibility | Protocol / Spec |
|
|
8
|
+
| :--- | :--- | :--- |
|
|
9
|
+
| **Surface** | Human-Agent Interaction | [A2UI Spec](/docs/a2ui) |
|
|
10
|
+
| **Memory** | Cross-Agent Knowledge | [Vector Workspace (Hive Mind)](/src/backend/cache) |
|
|
11
|
+
| **Logic** | Tool & Reasoning Handshake | [A2P Handshake](#a2p-handshake) |
|
|
12
|
+
| **Security** | Identity & Permissions | [GCP Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🤝 The A2P Handshake (Agent-to-Proxy)
|
|
17
|
+
|
|
18
|
+
When one agent calls another tool, it shouldn't just send raw text. It must send a **Reasoning Evidence Packet**.
|
|
19
|
+
|
|
20
|
+
### ❌ The "Old" Way (Brittle)
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"query": "What is the budget?",
|
|
24
|
+
"output": "The budget is $500k."
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### ✅ The "Cockpit" Way (Well-Architected)
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"trace_id": "tr-9942-x",
|
|
32
|
+
"reasoning_path": ["Fetch Schema", "Query BigQuery", "Apply PIIScrubber"],
|
|
33
|
+
"evidence": [
|
|
34
|
+
{ "source": "bq://finance.budget_2026", "assurance_score": 0.98 }
|
|
35
|
+
],
|
|
36
|
+
"content": {
|
|
37
|
+
"text": "The approved budget is $500k.",
|
|
38
|
+
"a2ui_surface": "DynamicBudgetChart"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 🛡️ Governance-as-Code for Swarms
|
|
44
|
+
|
|
45
|
+
On the Cockpit, every A2A transmission is automatically:
|
|
46
|
+
1. **Scrubbed**: PII is removed before leaving the Engine's VPC.
|
|
47
|
+
2. **Cached**: Similar cross-agent queries hit the **Hive Mind** instead of expensive LLM reasoning.
|
|
48
|
+
3. **Audited**: The `arch-review` tool verifies that your multi-agent graph doesn't have "Shadow Loops" (recursive infinite spend).
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## ⚡ Get Started with A2A
|
|
53
|
+
Use the Cockpit CLI to verify your multi-agent communication:
|
|
54
|
+
```bash
|
|
55
|
+
agent-ops audit --mode swarm --file multi_agent_entry.py
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
*This standard is being proposed to the Google Well-Architected Framework for AI Agents committee.*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentops-cockpit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Production-grade Agent Operations (AgentOps) Platform
|
|
5
5
|
Project-URL: Homepage, https://github.com/enriquekalven/agent-ops-cockpit
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/enriquekalven/agent-ops-cockpit/issues
|
|
@@ -11,6 +11,7 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Requires-Dist: gitpython>=3.1.0
|
|
14
|
+
Requires-Dist: mcp>=0.1.0
|
|
14
15
|
Requires-Dist: rich>=13.0.0
|
|
15
16
|
Requires-Dist: typer>=0.9.0
|
|
16
17
|
Description-Content-Type: text/markdown
|
|
@@ -18,10 +19,20 @@ Description-Content-Type: text/markdown
|
|
|
18
19
|
# 🕹️ AgentOps Cockpit
|
|
19
20
|
|
|
20
21
|
<div align="center">
|
|
22
|
+
<img src="https://raw.githubusercontent.com/enriquekalven/agent-cockpit/main/public/og-image.png" alt="AgentOps Cockpit Social Preview" width="100%" />
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div align="center">
|
|
26
|
+
<br />
|
|
27
|
+
<a href="https://deploy.cloud.google.com?repo=https://github.com/enriquekalven/agent-cockpit">
|
|
28
|
+
<img src="https://deploy.cloud.google.com/button.svg" alt="Deploy to Google Cloud" />
|
|
29
|
+
</a>
|
|
30
|
+
<br />
|
|
31
|
+
<br />
|
|
21
32
|
<img src="https://img.shields.io/github/stars/enriquekalven/agent-cockpit?style=for-the-badge&color=ffd700" alt="GitHub Stars" />
|
|
22
33
|
<img src="https://img.shields.io/github/license/enriquekalven/agent-cockpit?style=for-the-badge&color=007bff" alt="License" />
|
|
23
34
|
<img src="https://img.shields.io/badge/Google-Well--Architected-4285F4?style=for-the-badge&logo=google-cloud" alt="Google Well-Architected" />
|
|
24
|
-
<img src="https://img.shields.io/badge/
|
|
35
|
+
<img src="https://img.shields.io/badge/A2A_Standard-Enabled-10b981?style=for-the-badge" alt="A2A Standard" />
|
|
25
36
|
</div>
|
|
26
37
|
|
|
27
38
|
<br />
|
|
@@ -34,7 +45,12 @@ Description-Content-Type: text/markdown
|
|
|
34
45
|
---
|
|
35
46
|
|
|
36
47
|
## 📽️ The Mission
|
|
37
|
-
Most AI agent templates stop at a single Python file and an API key. **The AgentOps Cockpit** is for developers moving into production.
|
|
48
|
+
Most AI agent templates stop at a single Python file and an API key. **The AgentOps Cockpit** is for developers moving into production. It provides framework-agnostic governance, safety, and cost guardrails for the entire agentic ecosystem.
|
|
49
|
+
|
|
50
|
+
### Key Pillars:
|
|
51
|
+
- **Governance-as-Code**: Audit your agent against [Google Well-Architected](/docs/google-architecture) best practices.
|
|
52
|
+
- **Agentic Trinity**: Dedicated layers for the Engine (Logic), Face (UX), and Cockpit (Ops).
|
|
53
|
+
- **A2A Connectivity**: Implements the [Agent-to-Agent Transmission Standard](/A2A_GUIDE.md) for secure swarm orchestration.
|
|
38
54
|
|
|
39
55
|
---
|
|
40
56
|
|
|
@@ -86,6 +102,9 @@ Don't wait for your users to find prompt injections. Use the built-in Adversaria
|
|
|
86
102
|
### 🏛️ Arch Review & Framework Detection
|
|
87
103
|
Every agent in the cockpit is graded against a framework-aware checklist. The Cockpit intelligently detects your stack—**Google ADK**, **OpenAI Agentkit**, **Anthropic Claude**, **Microsoft AutoGen/Semantic Kernel**, **AWS Bedrock Agents**, or **CopilotKit**—and runs a tailored audit against corresponding production standards. Use `make arch-review` to verify your **Governance-as-Code**.
|
|
88
104
|
|
|
105
|
+
### 🕹️ MCP Connectivity Hub (Model Context Protocol)
|
|
106
|
+
Stop building one-off tool integrations. The Cockpit provides a unified hub for **MCP Servers**. Connect to Google Search, Slack, or your internal databases via the standardized Model Context Protocol for secure, audited tool execution.
|
|
107
|
+
|
|
89
108
|
### 🧗 Quality Hill Climbing (ADK Evaluation)
|
|
90
109
|
Following **Google ADK Evaluation** best practices, the Cockpit provides an iterative optimization loop. `make quality-baseline` runs your agent against a "Golden Dataset" using **LLM-as-a-Judge** scoring (Response Match & Tool Trajectory), climbing the quality curve until production-grade fidelity is reached.
|
|
91
110
|
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
# 🕹️ AgentOps Cockpit
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/enriquekalven/agent-cockpit/main/public/og-image.png" alt="AgentOps Cockpit Social Preview" width="100%" />
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
<br />
|
|
9
|
+
<a href="https://deploy.cloud.google.com?repo=https://github.com/enriquekalven/agent-cockpit">
|
|
10
|
+
<img src="https://deploy.cloud.google.com/button.svg" alt="Deploy to Google Cloud" />
|
|
11
|
+
</a>
|
|
12
|
+
<br />
|
|
13
|
+
<br />
|
|
4
14
|
<img src="https://img.shields.io/github/stars/enriquekalven/agent-cockpit?style=for-the-badge&color=ffd700" alt="GitHub Stars" />
|
|
5
15
|
<img src="https://img.shields.io/github/license/enriquekalven/agent-cockpit?style=for-the-badge&color=007bff" alt="License" />
|
|
6
16
|
<img src="https://img.shields.io/badge/Google-Well--Architected-4285F4?style=for-the-badge&logo=google-cloud" alt="Google Well-Architected" />
|
|
7
|
-
<img src="https://img.shields.io/badge/
|
|
17
|
+
<img src="https://img.shields.io/badge/A2A_Standard-Enabled-10b981?style=for-the-badge" alt="A2A Standard" />
|
|
8
18
|
</div>
|
|
9
19
|
|
|
10
20
|
<br />
|
|
@@ -17,7 +27,12 @@
|
|
|
17
27
|
---
|
|
18
28
|
|
|
19
29
|
## 📽️ The Mission
|
|
20
|
-
Most AI agent templates stop at a single Python file and an API key. **The AgentOps Cockpit** is for developers moving into production.
|
|
30
|
+
Most AI agent templates stop at a single Python file and an API key. **The AgentOps Cockpit** is for developers moving into production. It provides framework-agnostic governance, safety, and cost guardrails for the entire agentic ecosystem.
|
|
31
|
+
|
|
32
|
+
### Key Pillars:
|
|
33
|
+
- **Governance-as-Code**: Audit your agent against [Google Well-Architected](/docs/google-architecture) best practices.
|
|
34
|
+
- **Agentic Trinity**: Dedicated layers for the Engine (Logic), Face (UX), and Cockpit (Ops).
|
|
35
|
+
- **A2A Connectivity**: Implements the [Agent-to-Agent Transmission Standard](/A2A_GUIDE.md) for secure swarm orchestration.
|
|
21
36
|
|
|
22
37
|
---
|
|
23
38
|
|
|
@@ -69,6 +84,9 @@ Don't wait for your users to find prompt injections. Use the built-in Adversaria
|
|
|
69
84
|
### 🏛️ Arch Review & Framework Detection
|
|
70
85
|
Every agent in the cockpit is graded against a framework-aware checklist. The Cockpit intelligently detects your stack—**Google ADK**, **OpenAI Agentkit**, **Anthropic Claude**, **Microsoft AutoGen/Semantic Kernel**, **AWS Bedrock Agents**, or **CopilotKit**—and runs a tailored audit against corresponding production standards. Use `make arch-review` to verify your **Governance-as-Code**.
|
|
71
86
|
|
|
87
|
+
### 🕹️ MCP Connectivity Hub (Model Context Protocol)
|
|
88
|
+
Stop building one-off tool integrations. The Cockpit provides a unified hub for **MCP Servers**. Connect to Google Search, Slack, or your internal databases via the standardized Model Context Protocol for secure, audited tool execution.
|
|
89
|
+
|
|
72
90
|
### 🧗 Quality Hill Climbing (ADK Evaluation)
|
|
73
91
|
Following **Google ADK Evaluation** best practices, the Cockpit provides an iterative optimization loop. `make quality-baseline` runs your agent against a "Golden Dataset" using **LLM-as-a-Judge** scoring (Response Match & Tool Trajectory), climbing the quality curve until production-grade fidelity is reached.
|
|
74
92
|
|
|
Binary file
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentops-cockpit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Production-grade Agent Operations (AgentOps) Platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [
|
|
@@ -20,6 +20,7 @@ dependencies = [
|
|
|
20
20
|
"typer>=0.9.0",
|
|
21
21
|
"rich>=13.0.0",
|
|
22
22
|
"GitPython>=3.1.0",
|
|
23
|
+
"mcp>=0.1.0",
|
|
23
24
|
]
|
|
24
25
|
|
|
25
26
|
[project.urls]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Optional
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from mcp import ClientSession, StdioServerParameters
|
|
6
|
+
from mcp.client.stdio import stdio_client
|
|
7
|
+
|
|
8
|
+
class MCPHub:
|
|
9
|
+
"""
|
|
10
|
+
Model Context Protocol (MCP) Hub.
|
|
11
|
+
Provides a unified interface for tool discovery and execution across
|
|
12
|
+
multiple MCP servers (Google Search, SQL, internal tools).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.servers: Dict[str, StdioServerParameters] = {}
|
|
17
|
+
self.registry = {
|
|
18
|
+
"search": {"type": "mcp", "provider": "google-search", "server": "google-search-mcp"},
|
|
19
|
+
"db": {"type": "mcp", "provider": "alloydb", "server": "postgres-mcp"},
|
|
20
|
+
"legacy_crm": {"type": "rest", "provider": "internal", "status": "deprecated"}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def register_server(self, name: str, command: str, args: List[str] = None):
|
|
24
|
+
"""Registers a local MCP server."""
|
|
25
|
+
self.servers[name] = StdioServerParameters(
|
|
26
|
+
command=command,
|
|
27
|
+
args=args or [],
|
|
28
|
+
env=os.environ.copy()
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
async def execute_tool(self, tool_name: str, arguments: Dict[str, Any]):
|
|
32
|
+
"""
|
|
33
|
+
Executes a tool call using the Model Context Protocol.
|
|
34
|
+
"""
|
|
35
|
+
if tool_name not in self.registry:
|
|
36
|
+
raise ValueError(f"Tool {tool_name} not found in MCP registry.")
|
|
37
|
+
|
|
38
|
+
config = self.registry[tool_name]
|
|
39
|
+
|
|
40
|
+
# If it's a legacy tool, handle it separately
|
|
41
|
+
if config["type"] == "rest":
|
|
42
|
+
print(f"⚠️ Executing legacy REST tool: {tool_name}")
|
|
43
|
+
return await self._mock_legacy_exec(tool_name, arguments)
|
|
44
|
+
|
|
45
|
+
server_name = config.get("server")
|
|
46
|
+
if not server_name or server_name not in self.servers:
|
|
47
|
+
# Fallback to mock for demo/unconfigured environments
|
|
48
|
+
print(f"ℹ️ MCP Server '{server_name}' not configured. Running in simulated mode.")
|
|
49
|
+
return await self._mock_mcp_exec(tool_name, arguments)
|
|
50
|
+
|
|
51
|
+
# Real MCP Protocol Execution
|
|
52
|
+
async with stdio_client(self.servers[server_name]) as (read, write):
|
|
53
|
+
async with ClientSession(read, write) as session:
|
|
54
|
+
await session.initialize()
|
|
55
|
+
result = await session.call_tool(tool_name, arguments)
|
|
56
|
+
return {
|
|
57
|
+
"result": result.content,
|
|
58
|
+
"protocol": "mcp-v1",
|
|
59
|
+
"server": server_name
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async def _mock_mcp_exec(self, tool_name: str, args: Dict[str, Any]):
|
|
63
|
+
await asyncio.sleep(0.2)
|
|
64
|
+
return {
|
|
65
|
+
"result": f"Simulated MCP response for {tool_name}",
|
|
66
|
+
"protocol": "mcp-virtual",
|
|
67
|
+
"assurance": 0.95
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async def _mock_legacy_exec(self, tool_name: str, args: Dict[str, Any]):
|
|
71
|
+
await asyncio.sleep(0.5)
|
|
72
|
+
return {
|
|
73
|
+
"result": f"Legacy response for {tool_name}",
|
|
74
|
+
"protocol": "rest-legacy",
|
|
75
|
+
"warning": "MIGRATE_TO_MCP"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
global_mcp_hub = MCPHub()
|
|
79
|
+
# Example registration (commented out as it requires local binaries)
|
|
80
|
+
# global_mcp_hub.register_server("google-search-mcp", "npx", ["-y", "@modelcontextprotocol/server-google-search"])
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Optional
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from mcp import ClientSession, StdioServerParameters
|
|
6
|
+
from mcp.client.stdio import stdio_client
|
|
7
|
+
|
|
8
|
+
class MCPHub:
|
|
9
|
+
"""
|
|
10
|
+
Model Context Protocol (MCP) Hub.
|
|
11
|
+
Provides a unified interface for tool discovery and execution across
|
|
12
|
+
multiple MCP servers (Google Search, SQL, internal tools).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.servers: Dict[str, StdioServerParameters] = {}
|
|
17
|
+
self.registry = {
|
|
18
|
+
"search": {"type": "mcp", "provider": "google-search", "server": "google-search-mcp"},
|
|
19
|
+
"db": {"type": "mcp", "provider": "alloydb", "server": "postgres-mcp"},
|
|
20
|
+
"legacy_crm": {"type": "rest", "provider": "internal", "status": "deprecated"}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def register_server(self, name: str, command: str, args: List[str] = None):
|
|
24
|
+
"""Registers a local MCP server."""
|
|
25
|
+
self.servers[name] = StdioServerParameters(
|
|
26
|
+
command=command,
|
|
27
|
+
args=args or [],
|
|
28
|
+
env=os.environ.copy()
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
async def execute_tool(self, tool_name: str, arguments: Dict[str, Any]):
|
|
32
|
+
"""
|
|
33
|
+
Executes a tool call using the Model Context Protocol.
|
|
34
|
+
"""
|
|
35
|
+
if tool_name not in self.registry:
|
|
36
|
+
raise ValueError(f"Tool {tool_name} not found in MCP registry.")
|
|
37
|
+
|
|
38
|
+
config = self.registry[tool_name]
|
|
39
|
+
|
|
40
|
+
# If it's a legacy tool, handle it separately
|
|
41
|
+
if config["type"] == "rest":
|
|
42
|
+
print(f"⚠️ Executing legacy REST tool: {tool_name}")
|
|
43
|
+
return await self._mock_legacy_exec(tool_name, arguments)
|
|
44
|
+
|
|
45
|
+
server_name = config.get("server")
|
|
46
|
+
if not server_name or server_name not in self.servers:
|
|
47
|
+
# Fallback to mock for demo/unconfigured environments
|
|
48
|
+
print(f"ℹ️ MCP Server '{server_name}' not configured. Running in simulated mode.")
|
|
49
|
+
return await self._mock_mcp_exec(tool_name, arguments)
|
|
50
|
+
|
|
51
|
+
# Real MCP Protocol Execution
|
|
52
|
+
async with stdio_client(self.servers[server_name]) as (read, write):
|
|
53
|
+
async with ClientSession(read, write) as session:
|
|
54
|
+
await session.initialize()
|
|
55
|
+
result = await session.call_tool(tool_name, arguments)
|
|
56
|
+
return {
|
|
57
|
+
"result": result.content,
|
|
58
|
+
"protocol": "mcp-v1",
|
|
59
|
+
"server": server_name
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async def _mock_mcp_exec(self, tool_name: str, args: Dict[str, Any]):
|
|
63
|
+
await asyncio.sleep(0.2)
|
|
64
|
+
return {
|
|
65
|
+
"result": f"Simulated MCP response for {tool_name}",
|
|
66
|
+
"protocol": "mcp-virtual",
|
|
67
|
+
"assurance": 0.95
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async def _mock_legacy_exec(self, tool_name: str, args: Dict[str, Any]):
|
|
71
|
+
await asyncio.sleep(0.5)
|
|
72
|
+
return {
|
|
73
|
+
"result": f"Legacy response for {tool_name}",
|
|
74
|
+
"protocol": "rest-legacy",
|
|
75
|
+
"warning": "MIGRATE_TO_MCP"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
global_mcp_hub = MCPHub()
|
|
79
|
+
# Example registration (commented out as it requires local binaries)
|
|
80
|
+
# global_mcp_hub.register_server("google-search-mcp", "npx", ["-y", "@modelcontextprotocol/server-google-search"])
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# 📡 A2A (Agent-to-Agent) & The Cockpit
|
|
2
|
-
|
|
3
|
-
The **Agent-to-Agent (A2A) Protocol** enables distributed agent architectures. In the **AgentOps Cockpit**, A2A is managed as a first-class orchestration pattern.
|
|
4
|
-
|
|
5
|
-
## 🌉 The Cockpit's Role in A2A
|
|
6
|
-
While A2A handles the communication, the Cockpit handles the **Intelligence of the Connection**:
|
|
7
|
-
1. **Auditing**: The `make audit` command detects "Chatty A2A" patterns where too many turns occur between agents, suggesting tool-offloading or prompt-collapsing.
|
|
8
|
-
2. **Security**: `make red-team` tests the trust boundaries between agents to prevent "Side-Channel Injections" (where a compromised agent hacks another agent).
|
|
9
|
-
3. **Caching**: The **Hive Mind Cache** can cache results of expensive A2A sub-tasks across your entire agent mesh.
|
|
10
|
-
|
|
11
|
-
## 🛠️ Implementation
|
|
12
|
-
|
|
13
|
-
### 1. Exposing an Agent Service
|
|
14
|
-
Wrap your agent as an A2A service for other agents in the Cockpit to consume:
|
|
15
|
-
```python
|
|
16
|
-
from google.adk.a2a.utils.agent_to_a2a import to_a2a
|
|
17
|
-
from src.backend.agent import my_agent
|
|
18
|
-
|
|
19
|
-
# Standardizing the A2A port to 8001 (Engine is 8000)
|
|
20
|
-
a2a_app = to_a2a(my_agent, port=8001)
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### 2. Orchestration via MCP
|
|
24
|
-
The Cockpit uses the **Model Context Protocol (MCP)** to manage A2A connections:
|
|
25
|
-
- **Unified Tooling**: Remote agents appear as standard tools in `src/backend/ops/mcp_hub.py`.
|
|
26
|
-
- **Latency Tracking**: The Cockpit monitors the round-trip time between agent calls to ensure sub-second UI responsiveness.
|
|
27
|
-
|
|
28
|
-
## 🔄 A2UI + A2A Flow
|
|
29
|
-
When Agent A calls Agent B, the A2UI content from Agent B is automatically passed through to the final surface if the **Cockpit Middleware** is enabled:
|
|
30
|
-
```python
|
|
31
|
-
# In agent.py
|
|
32
|
-
shadow_router = ShadowRouter(v1_func=agent_v1, v2_func=agent_v2)
|
|
33
|
-
# Handles A2UI + A2A metadata automatically
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## 🏗️ Enterprise Mesh
|
|
37
|
-
In large-scale deployments, the Cockpit allows you to:
|
|
38
|
-
- **A/B Test Agents**: Split traffic between different expert agents using the Shadow Router.
|
|
39
|
-
- **Cost Guarding**: Set per-agent budgets to prevent one agent in the mesh from exhausting your quota.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from typing import List, Dict, Any
|
|
2
|
-
import asyncio
|
|
3
|
-
|
|
4
|
-
class MCPHub:
|
|
5
|
-
"""
|
|
6
|
-
Model Context Protocol (MCP) Hub.
|
|
7
|
-
Optimizes tool discovery, execution, and cost across multiple providers.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(self):
|
|
11
|
-
self.registry = {
|
|
12
|
-
"search": {"type": "mcp", "provider": "google-search", "status": "optimized"},
|
|
13
|
-
"db": {"type": "mcp", "provider": "alloydb-vector", "status": "optimized"},
|
|
14
|
-
"legacy_crm": {"type": "rest_api", "provider": "internal", "status": "deprecated"}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async def execute_tool(self, tool_name: str, args: Dict[str, Any]):
|
|
18
|
-
"""
|
|
19
|
-
Executes a tool via MCP if available, else falls back to legacy.
|
|
20
|
-
Logs metrics for the Flight Recorder.
|
|
21
|
-
"""
|
|
22
|
-
if tool_name not in self.registry:
|
|
23
|
-
raise ValueError(f"Tool {tool_name} not found in MCP Registry.")
|
|
24
|
-
|
|
25
|
-
config = self.registry[tool_name]
|
|
26
|
-
|
|
27
|
-
if config["status"] == "deprecated":
|
|
28
|
-
print(f"⚠️ WARNING: Using legacy Tool API for '{tool_name}'. Migrate to MCP for 30% lower latency.")
|
|
29
|
-
|
|
30
|
-
print(f"🛠️ Executing tool '{tool_name}' via {config['type']} protocol...")
|
|
31
|
-
await asyncio.sleep(0.1) # Simulating execution
|
|
32
|
-
|
|
33
|
-
return {"result": f"Data from {tool_name}", "protocol": config["type"]}
|
|
34
|
-
|
|
35
|
-
global_mcp_hub = MCPHub()
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from typing import List, Dict, Any
|
|
2
|
-
import asyncio
|
|
3
|
-
|
|
4
|
-
class MCPHub:
|
|
5
|
-
"""
|
|
6
|
-
Model Context Protocol (MCP) Hub.
|
|
7
|
-
Optimizes tool discovery, execution, and cost across multiple providers.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(self):
|
|
11
|
-
self.registry = {
|
|
12
|
-
"search": {"type": "mcp", "provider": "google-search", "status": "optimized"},
|
|
13
|
-
"db": {"type": "mcp", "provider": "alloydb-vector", "status": "optimized"},
|
|
14
|
-
"legacy_crm": {"type": "rest_api", "provider": "internal", "status": "deprecated"}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async def execute_tool(self, tool_name: str, args: Dict[str, Any]):
|
|
18
|
-
"""
|
|
19
|
-
Executes a tool via MCP if available, else falls back to legacy.
|
|
20
|
-
Logs metrics for the Flight Recorder.
|
|
21
|
-
"""
|
|
22
|
-
if tool_name not in self.registry:
|
|
23
|
-
raise ValueError(f"Tool {tool_name} not found in MCP Registry.")
|
|
24
|
-
|
|
25
|
-
config = self.registry[tool_name]
|
|
26
|
-
|
|
27
|
-
if config["status"] == "deprecated":
|
|
28
|
-
print(f"⚠️ WARNING: Using legacy Tool API for '{tool_name}'. Migrate to MCP for 30% lower latency.")
|
|
29
|
-
|
|
30
|
-
print(f"🛠️ Executing tool '{tool_name}' via {config['type']} protocol...")
|
|
31
|
-
await asyncio.sleep(0.1) # Simulating execution
|
|
32
|
-
|
|
33
|
-
return {"result": f"Data from {tool_name}", "protocol": config["type"]}
|
|
34
|
-
|
|
35
|
-
global_mcp_hub = MCPHub()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/components/lit-component-example.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cache/semantic_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/quality_climber.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/cost_optimizer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/memory_optimizer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/secret_scanner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|