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.
Files changed (101) hide show
  1. agentops_cockpit-0.4.0/A2A_GUIDE.md +58 -0
  2. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/PKG-INFO +22 -3
  3. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/README.md +20 -2
  4. agentops_cockpit-0.4.0/public/og-image.png +0 -0
  5. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/pyproject.toml +2 -1
  6. agentops_cockpit-0.4.0/src/agent_ops_cockpit/ops/mcp_hub.py +80 -0
  7. agentops_cockpit-0.4.0/src/backend/ops/mcp_hub.py +80 -0
  8. agentops_cockpit-0.3.0/A2A_GUIDE.md +0 -39
  9. agentops_cockpit-0.3.0/src/agent_ops_cockpit/ops/mcp_hub.py +0 -35
  10. agentops_cockpit-0.3.0/src/backend/ops/mcp_hub.py +0 -35
  11. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/.gitignore +0 -0
  12. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/BE_INTEGRATION_GUIDE.md +0 -0
  13. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/DEPLOYMENT.md +0 -0
  14. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/Dockerfile +0 -0
  15. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/LICENSE +0 -0
  16. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/Makefile +0 -0
  17. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/firebase.json +0 -0
  18. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/index.html +0 -0
  19. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/package.json +0 -0
  20. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/A2A_GUIDE.md +0 -0
  21. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/AGENT_OPS_STORY.md +0 -0
  22. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/BE_INTEGRATION_GUIDE.md +0 -0
  23. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/CLI_COMMANDS.md +0 -0
  24. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/DEPLOYMENT.md +0 -0
  25. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/DEVELOPMENT.md +0 -0
  26. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/GEMINI.md +0 -0
  27. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/GETTING_STARTED.md +0 -0
  28. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/README.md +0 -0
  29. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/cicd-workflow.png +0 -0
  30. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/diagrams/agentic-stack.png +0 -0
  31. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/diagrams/value-proposition.png +0 -0
  32. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/public/hero.png +0 -0
  33. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/App.tsx +0 -0
  34. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/A2UIRenderer.tsx +0 -0
  35. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/components/index.tsx +0 -0
  36. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/components/lit-component-example.ts +0 -0
  37. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/a2ui/types.ts +0 -0
  38. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/__init__.py +0 -0
  39. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cache/__init__.py +0 -0
  40. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cache/semantic_cache.py +0 -0
  41. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cli/__init__.py +0 -0
  42. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cli/main.py +0 -0
  43. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/cost_control.py +0 -0
  44. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/__init__.py +0 -0
  45. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/load_test.py +0 -0
  46. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/quality_climber.py +0 -0
  47. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/eval/red_team.py +0 -0
  48. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/__init__.py +0 -0
  49. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/arch_review.py +0 -0
  50. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/cost_optimizer.py +0 -0
  51. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/evidence.py +0 -0
  52. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/frameworks.py +0 -0
  53. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/memory_optimizer.py +0 -0
  54. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/orchestrator.py +0 -0
  55. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/pii_scrubber.py +0 -0
  56. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/reliability.py +0 -0
  57. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/secret_scanner.py +0 -0
  58. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/ops/ui_auditor.py +0 -0
  59. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/optimizer.py +0 -0
  60. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/shadow/__init__.py +0 -0
  61. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/agent_ops_cockpit/shadow/router.py +0 -0
  62. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/__init__.py +0 -0
  63. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/agent.py +0 -0
  64. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/cache/semantic_cache.py +0 -0
  65. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/cost_control.py +0 -0
  66. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/__init__.py +0 -0
  67. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/load_test.py +0 -0
  68. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/quality_climber.py +0 -0
  69. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/eval/red_team.py +0 -0
  70. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/__init__.py +0 -0
  71. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/arch_review.py +0 -0
  72. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/cost_optimizer.py +0 -0
  73. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/evidence.py +0 -0
  74. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/frameworks.py +0 -0
  75. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/memory_optimizer.py +0 -0
  76. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/orchestrator.py +0 -0
  77. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/pii_scrubber.py +0 -0
  78. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/reliability.py +0 -0
  79. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/secret_scanner.py +0 -0
  80. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/ops/ui_auditor.py +0 -0
  81. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/optimizer.py +0 -0
  82. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/shadow/router.py +0 -0
  83. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_agent.py +0 -0
  84. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_arch_review.py +0 -0
  85. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_frameworks.py +0 -0
  86. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_optimizer.py +0 -0
  87. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_quality_climber.py +0 -0
  88. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_red_team.py +0 -0
  89. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/backend/tests/test_secret_scanner.py +0 -0
  90. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/FlightRecorder.tsx +0 -0
  91. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/Home.tsx +0 -0
  92. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/OpsDashboard.tsx +0 -0
  93. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/Playground.tsx +0 -0
  94. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/components/ThemeToggle.tsx +0 -0
  95. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/docs/DocLayout.tsx +0 -0
  96. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/docs/DocPage.tsx +0 -0
  97. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/index.css +0 -0
  98. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/knowledge/example_policy.txt +0 -0
  99. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/src/main.tsx +0 -0
  100. {agentops_cockpit-0.3.0 → agentops_cockpit-0.4.0}/tsconfig.json +0 -0
  101. {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.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/Status-Day%202%20Operations-10b981?style=for-the-badge" alt="Status" />
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. While optimized for **ADK**, it provides framework-agnostic governance, safety, and cost guardrails for the entire agentic ecosystem—from CrewAI to LangGraph. Based on the **[Google Well-Architected Framework for Agents](/docs/google-architecture)**.
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/Status-Day%202%20Operations-10b981?style=for-the-badge" alt="Status" />
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. While optimized for **ADK**, it provides framework-agnostic governance, safety, and cost guardrails for the entire agentic ecosystem—from CrewAI to LangGraph. Based on the **[Google Well-Architected Framework for Agents](/docs/google-architecture)**.
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
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentops-cockpit"
7
- version = "0.3.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()