aegis-security-sdk 0.1.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.
- aegis_security_sdk-0.1.0/PKG-INFO +95 -0
- aegis_security_sdk-0.1.0/README.md +65 -0
- aegis_security_sdk-0.1.0/aegis_security_sdk.egg-info/PKG-INFO +95 -0
- aegis_security_sdk-0.1.0/aegis_security_sdk.egg-info/SOURCES.txt +82 -0
- aegis_security_sdk-0.1.0/aegis_security_sdk.egg-info/dependency_links.txt +1 -0
- aegis_security_sdk-0.1.0/aegis_security_sdk.egg-info/requires.txt +29 -0
- aegis_security_sdk-0.1.0/aegis_security_sdk.egg-info/top_level.txt +1 -0
- aegis_security_sdk-0.1.0/packages/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/adapters/__init__.py +4 -0
- aegis_security_sdk-0.1.0/packages/adapters/base/__init__.py +3 -0
- aegis_security_sdk-0.1.0/packages/adapters/base/adapter.py +26 -0
- aegis_security_sdk-0.1.0/packages/adapters/crewai/adapter.py +263 -0
- aegis_security_sdk-0.1.0/packages/adapters/langgraph/__init__.py +3 -0
- aegis_security_sdk-0.1.0/packages/adapters/langgraph/adapter.py +169 -0
- aegis_security_sdk-0.1.0/packages/aegis.py +780 -0
- aegis_security_sdk-0.1.0/packages/config.py +20 -0
- aegis_security_sdk-0.1.0/packages/context.py +36 -0
- aegis_security_sdk-0.1.0/packages/layers/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/base.py +19 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/exceptions.py +11 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/keys.py +27 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/capability_detector.py +87 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/intent_analysis.py +66 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/memory_validation.py +135 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/request_analyzer.py +174 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/request_validation.py +76 -0
- aegis_security_sdk-0.1.0/packages/layers/layer1/stages/risk_engine.py +71 -0
- aegis_security_sdk-0.1.0/packages/layers/layer2/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/layers/layer2/audit.py +38 -0
- aegis_security_sdk-0.1.0/packages/layers/layer2/engine.py +83 -0
- aegis_security_sdk-0.1.0/packages/layers/layer2/validators.py +108 -0
- aegis_security_sdk-0.1.0/packages/layers/layer5/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/layers/layer5/consumer.py +23 -0
- aegis_security_sdk-0.1.0/packages/memory/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/memory/adapters/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/memory/adapters/langgraph_adapter.py +64 -0
- aegis_security_sdk-0.1.0/packages/memory/conversation.py +36 -0
- aegis_security_sdk-0.1.0/packages/memory/manager.py +128 -0
- aegis_security_sdk-0.1.0/packages/memory/policies.py +42 -0
- aegis_security_sdk-0.1.0/packages/memory/provider.py +49 -0
- aegis_security_sdk-0.1.0/packages/memory/registry.py +44 -0
- aegis_security_sdk-0.1.0/packages/memory/retrieval.py +64 -0
- aegis_security_sdk-0.1.0/packages/memory/semantic.py +35 -0
- aegis_security_sdk-0.1.0/packages/models.py +173 -0
- aegis_security_sdk-0.1.0/packages/observability/__init__.py +4 -0
- aegis_security_sdk-0.1.0/packages/observability/models.py +549 -0
- aegis_security_sdk-0.1.0/packages/observability/store.py +175 -0
- aegis_security_sdk-0.1.0/packages/policy/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/policy/base.py +33 -0
- aegis_security_sdk-0.1.0/packages/policy/nl_policy.py +162 -0
- aegis_security_sdk-0.1.0/packages/providers.py +148 -0
- aegis_security_sdk-0.1.0/packages/runtime/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/events/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/events/bus.py +62 -0
- aegis_security_sdk-0.1.0/packages/runtime/events/models.py +107 -0
- aegis_security_sdk-0.1.0/packages/runtime/factory.py +56 -0
- aegis_security_sdk-0.1.0/packages/runtime/graph.py +53 -0
- aegis_security_sdk-0.1.0/packages/runtime/hooks/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/hooks/base.py +75 -0
- aegis_security_sdk-0.1.0/packages/runtime/hooks/policy.py +37 -0
- aegis_security_sdk-0.1.0/packages/runtime/kernel/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/kernel/kernel.py +501 -0
- aegis_security_sdk-0.1.0/packages/runtime/kernel/state.py +12 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/executor.py +80 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/kill_switch.py +44 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/monitor.py +36 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/normalizer.py +78 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/provider_executor.py +83 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/provider_registry.py +71 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/registry.py +67 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/retry.py +47 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/sanitizer.py +116 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/streaming.py +48 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/supervisor.py +61 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/timeout.py +42 -0
- aegis_security_sdk-0.1.0/packages/runtime/managers/tracker.py +50 -0
- aegis_security_sdk-0.1.0/packages/runtime/nodes/__init__.py +1 -0
- aegis_security_sdk-0.1.0/packages/runtime/nodes/executor.py +296 -0
- aegis_security_sdk-0.1.0/packages/runtime/nodes/planner.py +79 -0
- aegis_security_sdk-0.1.0/pyproject.toml +41 -0
- aegis_security_sdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aegis-security-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Aegis AI Security & Governance SDK
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: langchain-core>=0.3.0
|
|
8
|
+
Requires-Dist: langchain-groq>=0.2.0
|
|
9
|
+
Requires-Dist: langgraph>=0.2.0
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
12
|
+
Requires-Dist: httpx>=0.27.0
|
|
13
|
+
Provides-Extra: openai
|
|
14
|
+
Requires-Dist: langchain-openai>=0.2.0; extra == "openai"
|
|
15
|
+
Provides-Extra: anthropic
|
|
16
|
+
Requires-Dist: langchain-anthropic>=0.3.0; extra == "anthropic"
|
|
17
|
+
Provides-Extra: google
|
|
18
|
+
Requires-Dist: langchain-google-genai>=2.0.0; extra == "google"
|
|
19
|
+
Provides-Extra: nvidia
|
|
20
|
+
Requires-Dist: langchain-nvidia-ai-endpoints>=0.3.0; extra == "nvidia"
|
|
21
|
+
Provides-Extra: crewai
|
|
22
|
+
Requires-Dist: crewai>=0.80.0; extra == "crewai"
|
|
23
|
+
Requires-Dist: crewai-tools>=0.14.0; extra == "crewai"
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: aegis-security-sdk[openai]; extra == "all"
|
|
26
|
+
Requires-Dist: aegis-security-sdk[anthropic]; extra == "all"
|
|
27
|
+
Requires-Dist: aegis-security-sdk[google]; extra == "all"
|
|
28
|
+
Requires-Dist: aegis-security-sdk[nvidia]; extra == "all"
|
|
29
|
+
Requires-Dist: aegis-security-sdk[crewai]; extra == "all"
|
|
30
|
+
|
|
31
|
+
# 🛡️ Aegis SDK — Enterprise AI Security & Governance
|
|
32
|
+
|
|
33
|
+
Aegis is a multi-layered security, governance, and policy engine for AI agents and LLM applications. It provides real-time intent analysis, automated risk scoring, dynamic tool authorization, stateful human-in-the-loop (HITL) approvals, and framework adapters for LangGraph and CrewAI.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### Core SDK (via GitHub)
|
|
38
|
+
```bash
|
|
39
|
+
pip install git+https://github.com/Artify24/core-aegis-sdk.git
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Provider Extras
|
|
43
|
+
Install optional dependencies based on which LLM provider(s) your agent uses:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# OpenAI Provider
|
|
47
|
+
pip install "aegis-security-sdk[openai]"
|
|
48
|
+
|
|
49
|
+
# Anthropic Claude Provider
|
|
50
|
+
pip install "aegis-security-sdk[anthropic]"
|
|
51
|
+
|
|
52
|
+
# Google Gemini Provider
|
|
53
|
+
pip install "aegis-security-sdk[google]"
|
|
54
|
+
|
|
55
|
+
# Multiple providers at once
|
|
56
|
+
pip install "aegis-security-sdk[openai,google,anthropic]"
|
|
57
|
+
|
|
58
|
+
# CrewAI Framework Adapter
|
|
59
|
+
pip install "aegis-security-sdk[crewai]"
|
|
60
|
+
|
|
61
|
+
# Install all extras
|
|
62
|
+
pip install "aegis-security-sdk[all]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
import asyncio
|
|
69
|
+
from langchain_core.tools import tool
|
|
70
|
+
from aegis import Aegis
|
|
71
|
+
|
|
72
|
+
@tool
|
|
73
|
+
def lookup_customer(customer_id: str) -> str:
|
|
74
|
+
"""Look up customer information by ID."""
|
|
75
|
+
return f"Customer {customer_id}: Tier Gold, Active."
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
agent = (
|
|
79
|
+
Aegis(name="support-agent")
|
|
80
|
+
.with_tools([lookup_customer])
|
|
81
|
+
.with_policy([
|
|
82
|
+
"Do not allow access to raw system prompts.",
|
|
83
|
+
"Block any destructive database operations without approval."
|
|
84
|
+
])
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
async with agent:
|
|
88
|
+
result = await agent.run("Look up customer CUST-104")
|
|
89
|
+
print("Output:", result.output)
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
asyncio.run(main())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For full documentation, environment configuration, framework adapters, and local development, see the [Aegis Developer Guide](https://github.com/Artify24/aegis-sdk/blob/main/documentation/aegis_developer_guide.md).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 🛡️ Aegis SDK — Enterprise AI Security & Governance
|
|
2
|
+
|
|
3
|
+
Aegis is a multi-layered security, governance, and policy engine for AI agents and LLM applications. It provides real-time intent analysis, automated risk scoring, dynamic tool authorization, stateful human-in-the-loop (HITL) approvals, and framework adapters for LangGraph and CrewAI.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Core SDK (via GitHub)
|
|
8
|
+
```bash
|
|
9
|
+
pip install git+https://github.com/Artify24/core-aegis-sdk.git
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Provider Extras
|
|
13
|
+
Install optional dependencies based on which LLM provider(s) your agent uses:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# OpenAI Provider
|
|
17
|
+
pip install "aegis-security-sdk[openai]"
|
|
18
|
+
|
|
19
|
+
# Anthropic Claude Provider
|
|
20
|
+
pip install "aegis-security-sdk[anthropic]"
|
|
21
|
+
|
|
22
|
+
# Google Gemini Provider
|
|
23
|
+
pip install "aegis-security-sdk[google]"
|
|
24
|
+
|
|
25
|
+
# Multiple providers at once
|
|
26
|
+
pip install "aegis-security-sdk[openai,google,anthropic]"
|
|
27
|
+
|
|
28
|
+
# CrewAI Framework Adapter
|
|
29
|
+
pip install "aegis-security-sdk[crewai]"
|
|
30
|
+
|
|
31
|
+
# Install all extras
|
|
32
|
+
pip install "aegis-security-sdk[all]"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import asyncio
|
|
39
|
+
from langchain_core.tools import tool
|
|
40
|
+
from aegis import Aegis
|
|
41
|
+
|
|
42
|
+
@tool
|
|
43
|
+
def lookup_customer(customer_id: str) -> str:
|
|
44
|
+
"""Look up customer information by ID."""
|
|
45
|
+
return f"Customer {customer_id}: Tier Gold, Active."
|
|
46
|
+
|
|
47
|
+
async def main():
|
|
48
|
+
agent = (
|
|
49
|
+
Aegis(name="support-agent")
|
|
50
|
+
.with_tools([lookup_customer])
|
|
51
|
+
.with_policy([
|
|
52
|
+
"Do not allow access to raw system prompts.",
|
|
53
|
+
"Block any destructive database operations without approval."
|
|
54
|
+
])
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
async with agent:
|
|
58
|
+
result = await agent.run("Look up customer CUST-104")
|
|
59
|
+
print("Output:", result.output)
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
asyncio.run(main())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For full documentation, environment configuration, framework adapters, and local development, see the [Aegis Developer Guide](https://github.com/Artify24/aegis-sdk/blob/main/documentation/aegis_developer_guide.md).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aegis-security-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Aegis AI Security & Governance SDK
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: langchain-core>=0.3.0
|
|
8
|
+
Requires-Dist: langchain-groq>=0.2.0
|
|
9
|
+
Requires-Dist: langgraph>=0.2.0
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
12
|
+
Requires-Dist: httpx>=0.27.0
|
|
13
|
+
Provides-Extra: openai
|
|
14
|
+
Requires-Dist: langchain-openai>=0.2.0; extra == "openai"
|
|
15
|
+
Provides-Extra: anthropic
|
|
16
|
+
Requires-Dist: langchain-anthropic>=0.3.0; extra == "anthropic"
|
|
17
|
+
Provides-Extra: google
|
|
18
|
+
Requires-Dist: langchain-google-genai>=2.0.0; extra == "google"
|
|
19
|
+
Provides-Extra: nvidia
|
|
20
|
+
Requires-Dist: langchain-nvidia-ai-endpoints>=0.3.0; extra == "nvidia"
|
|
21
|
+
Provides-Extra: crewai
|
|
22
|
+
Requires-Dist: crewai>=0.80.0; extra == "crewai"
|
|
23
|
+
Requires-Dist: crewai-tools>=0.14.0; extra == "crewai"
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: aegis-security-sdk[openai]; extra == "all"
|
|
26
|
+
Requires-Dist: aegis-security-sdk[anthropic]; extra == "all"
|
|
27
|
+
Requires-Dist: aegis-security-sdk[google]; extra == "all"
|
|
28
|
+
Requires-Dist: aegis-security-sdk[nvidia]; extra == "all"
|
|
29
|
+
Requires-Dist: aegis-security-sdk[crewai]; extra == "all"
|
|
30
|
+
|
|
31
|
+
# 🛡️ Aegis SDK — Enterprise AI Security & Governance
|
|
32
|
+
|
|
33
|
+
Aegis is a multi-layered security, governance, and policy engine for AI agents and LLM applications. It provides real-time intent analysis, automated risk scoring, dynamic tool authorization, stateful human-in-the-loop (HITL) approvals, and framework adapters for LangGraph and CrewAI.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### Core SDK (via GitHub)
|
|
38
|
+
```bash
|
|
39
|
+
pip install git+https://github.com/Artify24/core-aegis-sdk.git
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Provider Extras
|
|
43
|
+
Install optional dependencies based on which LLM provider(s) your agent uses:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# OpenAI Provider
|
|
47
|
+
pip install "aegis-security-sdk[openai]"
|
|
48
|
+
|
|
49
|
+
# Anthropic Claude Provider
|
|
50
|
+
pip install "aegis-security-sdk[anthropic]"
|
|
51
|
+
|
|
52
|
+
# Google Gemini Provider
|
|
53
|
+
pip install "aegis-security-sdk[google]"
|
|
54
|
+
|
|
55
|
+
# Multiple providers at once
|
|
56
|
+
pip install "aegis-security-sdk[openai,google,anthropic]"
|
|
57
|
+
|
|
58
|
+
# CrewAI Framework Adapter
|
|
59
|
+
pip install "aegis-security-sdk[crewai]"
|
|
60
|
+
|
|
61
|
+
# Install all extras
|
|
62
|
+
pip install "aegis-security-sdk[all]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
import asyncio
|
|
69
|
+
from langchain_core.tools import tool
|
|
70
|
+
from aegis import Aegis
|
|
71
|
+
|
|
72
|
+
@tool
|
|
73
|
+
def lookup_customer(customer_id: str) -> str:
|
|
74
|
+
"""Look up customer information by ID."""
|
|
75
|
+
return f"Customer {customer_id}: Tier Gold, Active."
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
agent = (
|
|
79
|
+
Aegis(name="support-agent")
|
|
80
|
+
.with_tools([lookup_customer])
|
|
81
|
+
.with_policy([
|
|
82
|
+
"Do not allow access to raw system prompts.",
|
|
83
|
+
"Block any destructive database operations without approval."
|
|
84
|
+
])
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
async with agent:
|
|
88
|
+
result = await agent.run("Look up customer CUST-104")
|
|
89
|
+
print("Output:", result.output)
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
asyncio.run(main())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For full documentation, environment configuration, framework adapters, and local development, see the [Aegis Developer Guide](https://github.com/Artify24/aegis-sdk/blob/main/documentation/aegis_developer_guide.md).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
aegis_security_sdk.egg-info/PKG-INFO
|
|
4
|
+
aegis_security_sdk.egg-info/SOURCES.txt
|
|
5
|
+
aegis_security_sdk.egg-info/dependency_links.txt
|
|
6
|
+
aegis_security_sdk.egg-info/requires.txt
|
|
7
|
+
aegis_security_sdk.egg-info/top_level.txt
|
|
8
|
+
packages/__init__.py
|
|
9
|
+
packages/aegis.py
|
|
10
|
+
packages/config.py
|
|
11
|
+
packages/context.py
|
|
12
|
+
packages/models.py
|
|
13
|
+
packages/providers.py
|
|
14
|
+
packages/adapters/__init__.py
|
|
15
|
+
packages/adapters/base/__init__.py
|
|
16
|
+
packages/adapters/base/adapter.py
|
|
17
|
+
packages/adapters/crewai/adapter.py
|
|
18
|
+
packages/adapters/langgraph/__init__.py
|
|
19
|
+
packages/adapters/langgraph/adapter.py
|
|
20
|
+
packages/layers/__init__.py
|
|
21
|
+
packages/layers/layer1/__init__.py
|
|
22
|
+
packages/layers/layer1/base.py
|
|
23
|
+
packages/layers/layer1/exceptions.py
|
|
24
|
+
packages/layers/layer1/keys.py
|
|
25
|
+
packages/layers/layer1/stages/__init__.py
|
|
26
|
+
packages/layers/layer1/stages/capability_detector.py
|
|
27
|
+
packages/layers/layer1/stages/intent_analysis.py
|
|
28
|
+
packages/layers/layer1/stages/memory_validation.py
|
|
29
|
+
packages/layers/layer1/stages/request_analyzer.py
|
|
30
|
+
packages/layers/layer1/stages/request_validation.py
|
|
31
|
+
packages/layers/layer1/stages/risk_engine.py
|
|
32
|
+
packages/layers/layer2/__init__.py
|
|
33
|
+
packages/layers/layer2/audit.py
|
|
34
|
+
packages/layers/layer2/engine.py
|
|
35
|
+
packages/layers/layer2/validators.py
|
|
36
|
+
packages/layers/layer5/__init__.py
|
|
37
|
+
packages/layers/layer5/consumer.py
|
|
38
|
+
packages/memory/__init__.py
|
|
39
|
+
packages/memory/conversation.py
|
|
40
|
+
packages/memory/manager.py
|
|
41
|
+
packages/memory/policies.py
|
|
42
|
+
packages/memory/provider.py
|
|
43
|
+
packages/memory/registry.py
|
|
44
|
+
packages/memory/retrieval.py
|
|
45
|
+
packages/memory/semantic.py
|
|
46
|
+
packages/memory/adapters/__init__.py
|
|
47
|
+
packages/memory/adapters/langgraph_adapter.py
|
|
48
|
+
packages/observability/__init__.py
|
|
49
|
+
packages/observability/models.py
|
|
50
|
+
packages/observability/store.py
|
|
51
|
+
packages/policy/__init__.py
|
|
52
|
+
packages/policy/base.py
|
|
53
|
+
packages/policy/nl_policy.py
|
|
54
|
+
packages/runtime/__init__.py
|
|
55
|
+
packages/runtime/factory.py
|
|
56
|
+
packages/runtime/graph.py
|
|
57
|
+
packages/runtime/events/__init__.py
|
|
58
|
+
packages/runtime/events/bus.py
|
|
59
|
+
packages/runtime/events/models.py
|
|
60
|
+
packages/runtime/hooks/__init__.py
|
|
61
|
+
packages/runtime/hooks/base.py
|
|
62
|
+
packages/runtime/hooks/policy.py
|
|
63
|
+
packages/runtime/kernel/__init__.py
|
|
64
|
+
packages/runtime/kernel/kernel.py
|
|
65
|
+
packages/runtime/kernel/state.py
|
|
66
|
+
packages/runtime/managers/__init__.py
|
|
67
|
+
packages/runtime/managers/executor.py
|
|
68
|
+
packages/runtime/managers/kill_switch.py
|
|
69
|
+
packages/runtime/managers/monitor.py
|
|
70
|
+
packages/runtime/managers/normalizer.py
|
|
71
|
+
packages/runtime/managers/provider_executor.py
|
|
72
|
+
packages/runtime/managers/provider_registry.py
|
|
73
|
+
packages/runtime/managers/registry.py
|
|
74
|
+
packages/runtime/managers/retry.py
|
|
75
|
+
packages/runtime/managers/sanitizer.py
|
|
76
|
+
packages/runtime/managers/streaming.py
|
|
77
|
+
packages/runtime/managers/supervisor.py
|
|
78
|
+
packages/runtime/managers/timeout.py
|
|
79
|
+
packages/runtime/managers/tracker.py
|
|
80
|
+
packages/runtime/nodes/__init__.py
|
|
81
|
+
packages/runtime/nodes/executor.py
|
|
82
|
+
packages/runtime/nodes/planner.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
langchain-core>=0.3.0
|
|
2
|
+
langchain-groq>=0.2.0
|
|
3
|
+
langgraph>=0.2.0
|
|
4
|
+
pydantic>=2.0.0
|
|
5
|
+
python-dotenv>=1.0.0
|
|
6
|
+
httpx>=0.27.0
|
|
7
|
+
|
|
8
|
+
[all]
|
|
9
|
+
aegis-security-sdk[openai]
|
|
10
|
+
aegis-security-sdk[anthropic]
|
|
11
|
+
aegis-security-sdk[google]
|
|
12
|
+
aegis-security-sdk[nvidia]
|
|
13
|
+
aegis-security-sdk[crewai]
|
|
14
|
+
|
|
15
|
+
[anthropic]
|
|
16
|
+
langchain-anthropic>=0.3.0
|
|
17
|
+
|
|
18
|
+
[crewai]
|
|
19
|
+
crewai>=0.80.0
|
|
20
|
+
crewai-tools>=0.14.0
|
|
21
|
+
|
|
22
|
+
[google]
|
|
23
|
+
langchain-google-genai>=2.0.0
|
|
24
|
+
|
|
25
|
+
[nvidia]
|
|
26
|
+
langchain-nvidia-ai-endpoints>=0.3.0
|
|
27
|
+
|
|
28
|
+
[openai]
|
|
29
|
+
langchain-openai>=0.2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
packages
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Aegis internal subpackages module
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import Protocol, Any
|
|
2
|
+
from ...context import ExecutionContext
|
|
3
|
+
from ...observability.models import ExecutionReport
|
|
4
|
+
from ...models import ExecutionResult
|
|
5
|
+
|
|
6
|
+
class FrameworkAdapter(Protocol):
|
|
7
|
+
"""
|
|
8
|
+
Protocol for plugging an external agent framework into the Aegis Runtime.
|
|
9
|
+
Adapters handle Layer 3 (Execution) while keeping Layer 1, 2, and 4 intact.
|
|
10
|
+
"""
|
|
11
|
+
async def execute(
|
|
12
|
+
self,
|
|
13
|
+
context: ExecutionContext,
|
|
14
|
+
inputs: dict[str, Any],
|
|
15
|
+
report: ExecutionReport
|
|
16
|
+
) -> ExecutionResult:
|
|
17
|
+
"""
|
|
18
|
+
Execute the external framework.
|
|
19
|
+
|
|
20
|
+
The adapter is responsible for:
|
|
21
|
+
1. Invoking the framework's runtime.
|
|
22
|
+
2. Intercepting telemetry (tool calls, tokens, latency, steps).
|
|
23
|
+
3. Populating the `ExecutionReport` with the captured telemetry.
|
|
24
|
+
4. Returning a standardized `ExecutionResult`.
|
|
25
|
+
"""
|
|
26
|
+
...
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from typing import Any, Dict
|
|
3
|
+
from langchain_core.callbacks import BaseCallbackHandler
|
|
4
|
+
from langchain_core.messages import AIMessage
|
|
5
|
+
from crewai import Crew
|
|
6
|
+
|
|
7
|
+
from ...context import ExecutionContext
|
|
8
|
+
from ...observability.models import ExecutionReport, ToolCallRecord, ExecutionPlanStep
|
|
9
|
+
from ...models import ExecutionResult
|
|
10
|
+
from ..base.adapter import FrameworkAdapter
|
|
11
|
+
|
|
12
|
+
import uuid
|
|
13
|
+
|
|
14
|
+
class CrewAITelemetryHandler(BaseCallbackHandler):
|
|
15
|
+
"""
|
|
16
|
+
Captures synchronous and asynchronous callbacks from CrewAI execution.
|
|
17
|
+
CrewAI internally uses LangChain tools and LLMs, so these callbacks will fire.
|
|
18
|
+
"""
|
|
19
|
+
def __init__(self, report: ExecutionReport):
|
|
20
|
+
self.report = report
|
|
21
|
+
self.tool_starts: dict[str, dict[str, Any]] = {}
|
|
22
|
+
self.llm_starts: dict[str, float] = {}
|
|
23
|
+
self.step_counter = 0
|
|
24
|
+
|
|
25
|
+
def on_llm_start(self, serialized: dict[str, Any], prompts: list[str], **kwargs: Any) -> None:
|
|
26
|
+
run_id = str(kwargs.get("run_id", ""))
|
|
27
|
+
self.llm_starts[run_id] = time.time()
|
|
28
|
+
self.report.metrics.resources.llm_calls += 1
|
|
29
|
+
|
|
30
|
+
async def on_llm_start_async(self, serialized: dict[str, Any], prompts: list[str], **kwargs: Any) -> None:
|
|
31
|
+
self.on_llm_start(serialized, prompts, **kwargs)
|
|
32
|
+
|
|
33
|
+
def on_llm_end(self, response: Any, **kwargs: Any) -> None:
|
|
34
|
+
run_id = str(kwargs.get("run_id", ""))
|
|
35
|
+
start = self.llm_starts.get(run_id, time.time())
|
|
36
|
+
latency = (time.time() - start) * 1000
|
|
37
|
+
self.report.planner.latency_ms += latency
|
|
38
|
+
|
|
39
|
+
# Check for tool calls to populate execution plan
|
|
40
|
+
if hasattr(response, "generations"):
|
|
41
|
+
for gen_list in response.generations:
|
|
42
|
+
for gen in gen_list:
|
|
43
|
+
msg = getattr(gen, "message", None)
|
|
44
|
+
if isinstance(msg, AIMessage) and hasattr(msg, "tool_calls") and msg.tool_calls:
|
|
45
|
+
self.report.planner.planning_iterations += 1
|
|
46
|
+
for tc in msg.tool_calls:
|
|
47
|
+
self.step_counter += 1
|
|
48
|
+
tool_name = tc.get("name", "unknown")
|
|
49
|
+
args = tc.get("args", {})
|
|
50
|
+
arg_keys = list(args.keys())[:3]
|
|
51
|
+
purpose_hint = ", ".join(arg_keys)
|
|
52
|
+
self.report.execution_plan.append(ExecutionPlanStep(
|
|
53
|
+
step=self.step_counter,
|
|
54
|
+
tool=tool_name,
|
|
55
|
+
purpose=f"Execute {tool_name}" + (f" ({purpose_hint})" if purpose_hint else ""),
|
|
56
|
+
))
|
|
57
|
+
|
|
58
|
+
async def on_llm_end_async(self, response: Any, **kwargs: Any) -> None:
|
|
59
|
+
self.on_llm_end(response, **kwargs)
|
|
60
|
+
|
|
61
|
+
def on_tool_start(self, serialized: dict[str, Any], input_str: str, **kwargs: Any) -> None:
|
|
62
|
+
run_id = str(kwargs.get("run_id", ""))
|
|
63
|
+
self.tool_starts[run_id] = {
|
|
64
|
+
"start": time.time(),
|
|
65
|
+
"name": serialized.get("name", "unknown") if serialized else "unknown",
|
|
66
|
+
"input": input_str
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async def on_tool_start_async(self, serialized: dict[str, Any], input_str: str, **kwargs: Any) -> None:
|
|
70
|
+
self.on_tool_start(serialized, input_str, **kwargs)
|
|
71
|
+
|
|
72
|
+
def on_tool_end(self, output: str, **kwargs: Any) -> None:
|
|
73
|
+
run_id = str(kwargs.get("run_id", ""))
|
|
74
|
+
tdata = self.tool_starts.get(run_id)
|
|
75
|
+
if tdata:
|
|
76
|
+
duration = (time.time() - tdata["start"]) * 1000
|
|
77
|
+
tc = ToolCallRecord(
|
|
78
|
+
tool_call_id=run_id,
|
|
79
|
+
tool=tdata["name"],
|
|
80
|
+
status="SUCCESS",
|
|
81
|
+
duration_ms=round(duration, 2),
|
|
82
|
+
input_summary=tdata["input"],
|
|
83
|
+
output_summary=str(output)
|
|
84
|
+
)
|
|
85
|
+
self.report.tool_calls.append(tc)
|
|
86
|
+
self.report.add_timeline_event(
|
|
87
|
+
"Runtime",
|
|
88
|
+
f"Tool Executed: {tdata['name']}",
|
|
89
|
+
metadata={"tool_call_id": run_id, "status": "SUCCESS", "duration_ms": duration}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
async def on_tool_end_async(self, output: str, **kwargs: Any) -> None:
|
|
93
|
+
self.on_tool_end(output, **kwargs)
|
|
94
|
+
|
|
95
|
+
def on_tool_error(self, error: BaseException, **kwargs: Any) -> None:
|
|
96
|
+
run_id = str(kwargs.get("run_id", ""))
|
|
97
|
+
tdata = self.tool_starts.get(run_id)
|
|
98
|
+
if tdata:
|
|
99
|
+
duration = (time.time() - tdata["start"]) * 1000
|
|
100
|
+
tc = ToolCallRecord(
|
|
101
|
+
tool_call_id=run_id,
|
|
102
|
+
tool=tdata["name"],
|
|
103
|
+
status="FAILED",
|
|
104
|
+
duration_ms=round(duration, 2),
|
|
105
|
+
input_summary=tdata["input"],
|
|
106
|
+
error=str(error)
|
|
107
|
+
)
|
|
108
|
+
self.report.tool_calls.append(tc)
|
|
109
|
+
self.report.add_timeline_event(
|
|
110
|
+
"Runtime",
|
|
111
|
+
f"Tool Failed: {tdata['name']}",
|
|
112
|
+
metadata={"tool_call_id": run_id, "status": "FAILED", "duration_ms": duration}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
async def on_tool_error_async(self, error: BaseException, **kwargs: Any) -> None:
|
|
116
|
+
self.on_tool_error(error, **kwargs)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class CrewAIAdapter(FrameworkAdapter):
|
|
120
|
+
"""
|
|
121
|
+
Adapter for executing CrewAI crews through Aegis.
|
|
122
|
+
"""
|
|
123
|
+
def __init__(self, crew: Crew):
|
|
124
|
+
self.crew = crew
|
|
125
|
+
|
|
126
|
+
def _wrap_tool(self, tool: Any, report: ExecutionReport) -> Any:
|
|
127
|
+
tool_name = getattr(tool, "name", str(tool))
|
|
128
|
+
orig_run = getattr(tool, "_run", None) or getattr(tool, "run", None) or getattr(tool, "func", None)
|
|
129
|
+
if not orig_run or getattr(tool, "_aegis_wrapped", False):
|
|
130
|
+
return tool
|
|
131
|
+
|
|
132
|
+
step_counter = [len(report.execution_plan) + 1]
|
|
133
|
+
|
|
134
|
+
def wrapped_run(*args: Any, **kwargs: Any) -> Any:
|
|
135
|
+
t_start = time.time()
|
|
136
|
+
tool_id = str(uuid.uuid4())
|
|
137
|
+
input_summary = str(kwargs) if kwargs else (str(args) if args else "")
|
|
138
|
+
|
|
139
|
+
report.execution_plan.append(ExecutionPlanStep(
|
|
140
|
+
step=step_counter[0],
|
|
141
|
+
tool=tool_name,
|
|
142
|
+
purpose=f"Execute {tool_name}"
|
|
143
|
+
))
|
|
144
|
+
step_counter[0] += 1
|
|
145
|
+
|
|
146
|
+
status = "SUCCESS"
|
|
147
|
+
error_msg = None
|
|
148
|
+
result = None
|
|
149
|
+
try:
|
|
150
|
+
result = orig_run(*args, **kwargs)
|
|
151
|
+
return result
|
|
152
|
+
except Exception as e:
|
|
153
|
+
status = "FAILED"
|
|
154
|
+
error_msg = str(e)
|
|
155
|
+
raise e
|
|
156
|
+
finally:
|
|
157
|
+
duration_ms = round((time.time() - t_start) * 1000, 2)
|
|
158
|
+
output_str = str(result) if result is not None else (error_msg or "")
|
|
159
|
+
|
|
160
|
+
tc = ToolCallRecord(
|
|
161
|
+
tool_call_id=tool_id,
|
|
162
|
+
tool=tool_name,
|
|
163
|
+
status=status,
|
|
164
|
+
duration_ms=duration_ms,
|
|
165
|
+
input_summary=input_summary[:300],
|
|
166
|
+
output_summary=output_str[:300],
|
|
167
|
+
error=error_msg
|
|
168
|
+
)
|
|
169
|
+
report.tool_calls.append(tc)
|
|
170
|
+
report.add_timeline_event(
|
|
171
|
+
"Runtime",
|
|
172
|
+
f"Tool Executed: {tool_name}" if status == "SUCCESS" else f"Tool Failed: {tool_name}",
|
|
173
|
+
metadata={"tool_call_id": tool_id, "status": status, "duration_ms": duration_ms}
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if hasattr(tool, "_run"):
|
|
177
|
+
tool._run = wrapped_run
|
|
178
|
+
elif hasattr(tool, "run"):
|
|
179
|
+
tool.run = wrapped_run
|
|
180
|
+
elif hasattr(tool, "func"):
|
|
181
|
+
tool.func = wrapped_run
|
|
182
|
+
|
|
183
|
+
setattr(tool, "_aegis_wrapped", True)
|
|
184
|
+
return tool
|
|
185
|
+
|
|
186
|
+
async def execute(
|
|
187
|
+
self,
|
|
188
|
+
context: ExecutionContext,
|
|
189
|
+
inputs: dict[str, Any],
|
|
190
|
+
report: ExecutionReport
|
|
191
|
+
) -> ExecutionResult:
|
|
192
|
+
|
|
193
|
+
# 1. Setup Telemetry Handler
|
|
194
|
+
handler = CrewAITelemetryHandler(report)
|
|
195
|
+
|
|
196
|
+
# 2. Inject handler & wrap tools for telemetry capture
|
|
197
|
+
for agent in self.crew.agents:
|
|
198
|
+
if getattr(agent, "callbacks", None) is None:
|
|
199
|
+
agent.callbacks = []
|
|
200
|
+
agent.callbacks.append(handler)
|
|
201
|
+
|
|
202
|
+
if hasattr(agent, "tools") and agent.tools:
|
|
203
|
+
wrapped_tools = []
|
|
204
|
+
for tool in agent.tools:
|
|
205
|
+
wrapped_tools.append(self._wrap_tool(tool, report))
|
|
206
|
+
agent.tools = wrapped_tools
|
|
207
|
+
|
|
208
|
+
report.add_timeline_event("Planner", "CrewAI Execution Started")
|
|
209
|
+
start_time = time.time()
|
|
210
|
+
|
|
211
|
+
# 3. Clean Inputs
|
|
212
|
+
clean_inputs = {}
|
|
213
|
+
if "messages" in inputs and inputs["messages"]:
|
|
214
|
+
prompt = inputs["messages"][-1].content
|
|
215
|
+
clean_inputs["prompt"] = prompt
|
|
216
|
+
else:
|
|
217
|
+
clean_inputs["prompt"] = context.request.prompt
|
|
218
|
+
|
|
219
|
+
# 4. Invoke Crew
|
|
220
|
+
crew_output = await self.crew.kickoff_async(inputs=clean_inputs)
|
|
221
|
+
|
|
222
|
+
elapsed = (time.time() - start_time) * 1000
|
|
223
|
+
report.add_timeline_event("Planner", "CrewAI Execution Finished")
|
|
224
|
+
|
|
225
|
+
output_str = crew_output.raw if hasattr(crew_output, "raw") else str(crew_output)
|
|
226
|
+
|
|
227
|
+
# 5. Extract token usage if available from CrewOutput
|
|
228
|
+
if hasattr(crew_output, "token_usage") and crew_output.token_usage:
|
|
229
|
+
usage = crew_output.token_usage
|
|
230
|
+
if isinstance(usage, dict):
|
|
231
|
+
p_tokens = usage.get("prompt_tokens", 0) or usage.get("input_tokens", 0)
|
|
232
|
+
c_tokens = usage.get("completion_tokens", 0) or usage.get("output_tokens", 0)
|
|
233
|
+
t_tokens = usage.get("total_tokens", 0) or (p_tokens + c_tokens)
|
|
234
|
+
llm_calls = usage.get("successful_requests", 1)
|
|
235
|
+
else:
|
|
236
|
+
p_tokens = getattr(usage, "prompt_tokens", 0) or getattr(usage, "input_tokens", 0)
|
|
237
|
+
c_tokens = getattr(usage, "completion_tokens", 0) or getattr(usage, "output_tokens", 0)
|
|
238
|
+
t_tokens = getattr(usage, "total_tokens", 0) or (p_tokens + c_tokens)
|
|
239
|
+
llm_calls = getattr(usage, "successful_requests", 1)
|
|
240
|
+
|
|
241
|
+
report.planner.input_tokens = p_tokens
|
|
242
|
+
report.planner.output_tokens = c_tokens
|
|
243
|
+
report.planner.total_tokens = t_tokens
|
|
244
|
+
report.planner.total_llm_calls = llm_calls if llm_calls else 1
|
|
245
|
+
report.planner.planning_iterations = max(len(report.execution_plan), 1)
|
|
246
|
+
report.metrics.resources.llm_calls = report.planner.total_llm_calls
|
|
247
|
+
|
|
248
|
+
report.metrics.cost.input_tokens = p_tokens
|
|
249
|
+
report.metrics.cost.output_tokens = c_tokens
|
|
250
|
+
report.metrics.cost.total_tokens = t_tokens
|
|
251
|
+
|
|
252
|
+
# 6. Finalize tool metrics
|
|
253
|
+
report.metrics.resources.tool_calls = len(report.tool_calls)
|
|
254
|
+
total_tool_latency = sum(tc.duration_ms for tc in report.tool_calls)
|
|
255
|
+
report.metrics.performance.tool_latency_ms = round(total_tool_latency, 2)
|
|
256
|
+
|
|
257
|
+
return ExecutionResult(
|
|
258
|
+
output=output_str,
|
|
259
|
+
tool_calls=[tc.tool for tc in report.tool_calls],
|
|
260
|
+
tokens_used=report.planner.total_tokens,
|
|
261
|
+
execution_time=elapsed,
|
|
262
|
+
metadata={"layer1": getattr(context, "layer1", {})}
|
|
263
|
+
)
|