cortexhub 0.1.5__tar.gz → 0.1.7__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.
- {cortexhub-0.1.5 → cortexhub-0.1.7}/PKG-INFO +1 -1
- {cortexhub-0.1.5 → cortexhub-0.1.7}/pyproject.toml +1 -1
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/claude_agents.py +0 -7
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/crewai.py +0 -7
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/langgraph.py +0 -6
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/openai_agents.py +0 -7
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/backend/client.py +58 -39
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/client.py +1 -1
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/version.py +1 -1
- {cortexhub-0.1.5 → cortexhub-0.1.7}/.gitignore +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/LICENSE +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/README.md +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/adapters/base.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/audit/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/audit/events.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/auto_protect.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/backend/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/config.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/context/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/context/enricher.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/errors.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/frameworks.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/guardrails/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/guardrails/injection.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/guardrails/pii.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/guardrails/secrets.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/interceptors/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/interceptors/llm.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/interceptors/mcp.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/pipeline.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/effects.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/evaluator.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/loader.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/models.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/policy/sync.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/telemetry/__init__.py +0 -0
- {cortexhub-0.1.5 → cortexhub-0.1.7}/src/cortexhub/telemetry/otel.py +0 -0
|
@@ -94,13 +94,6 @@ class ClaudeAgentsAdapter(ToolAdapter):
|
|
|
94
94
|
return
|
|
95
95
|
|
|
96
96
|
cortex_hub = self.cortex_hub
|
|
97
|
-
tools = self._discover_tools()
|
|
98
|
-
if tools:
|
|
99
|
-
cortex_hub.backend.register_tool_inventory(
|
|
100
|
-
agent_id=cortex_hub.agent_id,
|
|
101
|
-
framework=self.framework_name,
|
|
102
|
-
tools=tools,
|
|
103
|
-
)
|
|
104
97
|
|
|
105
98
|
# Store original decorator
|
|
106
99
|
if not hasattr(claude_agent_sdk, _ORIGINAL_TOOL_ATTR):
|
|
@@ -70,13 +70,6 @@ class CrewAIAdapter(ToolAdapter):
|
|
|
70
70
|
from crewai.tools.structured_tool import CrewStructuredTool
|
|
71
71
|
|
|
72
72
|
cortex_hub = self.cortex_hub
|
|
73
|
-
tools = self._discover_tools()
|
|
74
|
-
if tools:
|
|
75
|
-
cortex_hub.backend.register_tool_inventory(
|
|
76
|
-
agent_id=cortex_hub.agent_id,
|
|
77
|
-
framework=self.framework_name,
|
|
78
|
-
tools=tools,
|
|
79
|
-
)
|
|
80
73
|
|
|
81
74
|
# Patch CrewStructuredTool.invoke (primary execution path)
|
|
82
75
|
if not getattr(CrewStructuredTool, _PATCHED_ATTR, False):
|
|
@@ -411,12 +411,6 @@ class LangGraphAdapter(ToolAdapter):
|
|
|
411
411
|
name = tool.get("name") or "unknown_tool"
|
|
412
412
|
self._discovered_tools[name] = tool
|
|
413
413
|
|
|
414
|
-
self.cortex_hub.backend.register_tool_inventory(
|
|
415
|
-
agent_id=self.cortex_hub.agent_id,
|
|
416
|
-
framework=self.framework_name,
|
|
417
|
-
tools=list(self._discovered_tools.values()),
|
|
418
|
-
)
|
|
419
|
-
|
|
420
414
|
def _normalize_tools(self, tools: Any) -> list[dict[str, Any]]:
|
|
421
415
|
"""Convert tool objects to inventory payloads."""
|
|
422
416
|
normalized: list[dict[str, Any]] = []
|
|
@@ -67,13 +67,6 @@ class OpenAIAgentsAdapter(ToolAdapter):
|
|
|
67
67
|
return
|
|
68
68
|
|
|
69
69
|
cortex_hub = self.cortex_hub
|
|
70
|
-
tools = self._discover_tools()
|
|
71
|
-
if tools:
|
|
72
|
-
cortex_hub.backend.register_tool_inventory(
|
|
73
|
-
agent_id=cortex_hub.agent_id,
|
|
74
|
-
framework=self.framework_name,
|
|
75
|
-
tools=tools,
|
|
76
|
-
)
|
|
77
70
|
|
|
78
71
|
# Store original function_tool decorator
|
|
79
72
|
if not hasattr(tool_module, _ORIGINAL_FUNCTION_TOOL_ATTR):
|
|
@@ -7,7 +7,6 @@ import httpx
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
|
|
10
|
-
from cortexhub.version import __version__
|
|
11
10
|
|
|
12
11
|
logger = structlog.get_logger(__name__)
|
|
13
12
|
|
|
@@ -92,7 +91,7 @@ class BackendClient:
|
|
|
92
91
|
timeout=10.0,
|
|
93
92
|
)
|
|
94
93
|
|
|
95
|
-
def validate_api_key(self) -> tuple[bool, SDKConfig | None]:
|
|
94
|
+
def validate_api_key(self, *, agent_id: str | None = None) -> tuple[bool, SDKConfig | None]:
|
|
96
95
|
"""Validate API key with backend and get SDK configuration.
|
|
97
96
|
|
|
98
97
|
Returns:
|
|
@@ -127,7 +126,46 @@ class BackendClient:
|
|
|
127
126
|
|
|
128
127
|
# Convert policy objects to Cedar string if needed
|
|
129
128
|
raw_policies = policies_data.get("policies", [])
|
|
129
|
+
if agent_id:
|
|
130
|
+
raw_policies = [
|
|
131
|
+
policy for policy in raw_policies if policy.get("agent_id") == agent_id
|
|
132
|
+
]
|
|
130
133
|
guardrail_configs: dict[str, GuardrailConfig] = {}
|
|
134
|
+
|
|
135
|
+
def _merge_guardrail_config(
|
|
136
|
+
existing: GuardrailConfig | None,
|
|
137
|
+
incoming: GuardrailConfig,
|
|
138
|
+
) -> GuardrailConfig:
|
|
139
|
+
if not existing:
|
|
140
|
+
return incoming
|
|
141
|
+
priority = {"block": 3, "redact": 2, "allow": 1}
|
|
142
|
+
action = (
|
|
143
|
+
incoming.action
|
|
144
|
+
if priority.get(incoming.action, 0) > priority.get(existing.action, 0)
|
|
145
|
+
else existing.action
|
|
146
|
+
)
|
|
147
|
+
if existing.pii_types is None or incoming.pii_types is None:
|
|
148
|
+
pii_types = None
|
|
149
|
+
else:
|
|
150
|
+
pii_types = sorted(set(existing.pii_types + incoming.pii_types))
|
|
151
|
+
if existing.secret_types is None or incoming.secret_types is None:
|
|
152
|
+
secret_types = None
|
|
153
|
+
else:
|
|
154
|
+
secret_types = sorted(set(existing.secret_types + incoming.secret_types))
|
|
155
|
+
custom_patterns = (existing.custom_patterns or []) + (incoming.custom_patterns or [])
|
|
156
|
+
if existing.redaction_scope == "both" or incoming.redaction_scope == "both":
|
|
157
|
+
redaction_scope = "both"
|
|
158
|
+
elif existing.redaction_scope != incoming.redaction_scope:
|
|
159
|
+
redaction_scope = "both"
|
|
160
|
+
else:
|
|
161
|
+
redaction_scope = existing.redaction_scope
|
|
162
|
+
return GuardrailConfig(
|
|
163
|
+
action=action,
|
|
164
|
+
pii_types=pii_types,
|
|
165
|
+
secret_types=secret_types,
|
|
166
|
+
custom_patterns=custom_patterns,
|
|
167
|
+
redaction_scope=redaction_scope,
|
|
168
|
+
)
|
|
131
169
|
|
|
132
170
|
if isinstance(raw_policies, list):
|
|
133
171
|
# Backend returns list of policy objects - extract Cedar code
|
|
@@ -171,12 +209,16 @@ class BackendClient:
|
|
|
171
209
|
description=cp.get("description"),
|
|
172
210
|
enabled=cp.get("enabled", True),
|
|
173
211
|
))
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
212
|
+
merged = _merge_guardrail_config(
|
|
213
|
+
guardrail_configs.get("pii"),
|
|
214
|
+
GuardrailConfig(
|
|
215
|
+
action=gc.get("action", "redact"),
|
|
216
|
+
pii_types=gc.get("pii_types"),
|
|
217
|
+
custom_patterns=custom_patterns if custom_patterns else None,
|
|
218
|
+
redaction_scope=gc.get("redaction_scope", "both"),
|
|
219
|
+
),
|
|
179
220
|
)
|
|
221
|
+
guardrail_configs["pii"] = merged
|
|
180
222
|
elif "secrets" in policy_key:
|
|
181
223
|
custom_patterns = []
|
|
182
224
|
raw_patterns = gc.get("custom_patterns") or []
|
|
@@ -187,12 +229,16 @@ class BackendClient:
|
|
|
187
229
|
description=cp.get("description"),
|
|
188
230
|
enabled=cp.get("enabled", True),
|
|
189
231
|
))
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
232
|
+
merged = _merge_guardrail_config(
|
|
233
|
+
guardrail_configs.get("secrets"),
|
|
234
|
+
GuardrailConfig(
|
|
235
|
+
action=gc.get("action", "redact"),
|
|
236
|
+
secret_types=gc.get("secret_types"),
|
|
237
|
+
custom_patterns=custom_patterns if custom_patterns else None,
|
|
238
|
+
redaction_scope=gc.get("redaction_scope", "both"),
|
|
239
|
+
),
|
|
195
240
|
)
|
|
241
|
+
guardrail_configs["secrets"] = merged
|
|
196
242
|
policies_str = "\n".join(cedar_parts)
|
|
197
243
|
else:
|
|
198
244
|
policies_str = raw_policies or ""
|
|
@@ -254,33 +300,6 @@ class BackendClient:
|
|
|
254
300
|
if self._client:
|
|
255
301
|
self._client.close()
|
|
256
302
|
|
|
257
|
-
def register_tool_inventory(
|
|
258
|
-
self,
|
|
259
|
-
*,
|
|
260
|
-
agent_id: str,
|
|
261
|
-
framework: str,
|
|
262
|
-
tools: list[dict],
|
|
263
|
-
) -> dict[str, Any]:
|
|
264
|
-
"""Register agent tool inventory on init. Overwrites previous."""
|
|
265
|
-
|
|
266
|
-
if not self._client:
|
|
267
|
-
return {"agent_id": agent_id, "tools_count": 0}
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
response = self._client.post(
|
|
271
|
-
"/tool-inventory",
|
|
272
|
-
json={
|
|
273
|
-
"agent_id": agent_id,
|
|
274
|
-
"framework": framework,
|
|
275
|
-
"sdk_version": __version__,
|
|
276
|
-
"tools": tools,
|
|
277
|
-
},
|
|
278
|
-
)
|
|
279
|
-
return response.json()
|
|
280
|
-
except Exception as e:
|
|
281
|
-
logger.warning("Failed to register tool inventory", error=str(e))
|
|
282
|
-
return {"agent_id": agent_id, "tools_count": len(tools)}
|
|
283
|
-
|
|
284
303
|
def create_approval(
|
|
285
304
|
self,
|
|
286
305
|
*,
|
|
@@ -159,7 +159,7 @@ class CortexHub:
|
|
|
159
159
|
|
|
160
160
|
# Validate API key and get configuration (including policies)
|
|
161
161
|
self.backend = BackendClient(self.api_key, self.api_base_url)
|
|
162
|
-
is_valid, sdk_config = self.backend.validate_api_key()
|
|
162
|
+
is_valid, sdk_config = self.backend.validate_api_key(agent_id=self.agent_id)
|
|
163
163
|
|
|
164
164
|
if not is_valid:
|
|
165
165
|
raise ConfigurationError(
|
|
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
|