cortexhub 0.1.5__py3-none-any.whl → 0.1.8__py3-none-any.whl
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/adapters/claude_agents.py +9 -7
- cortexhub/adapters/crewai.py +0 -7
- cortexhub/adapters/langgraph.py +2 -6
- cortexhub/adapters/openai_agents.py +2 -7
- cortexhub/backend/client.py +58 -39
- cortexhub/client.py +80 -20
- cortexhub/pipeline.py +8 -0
- cortexhub/version.py +1 -1
- {cortexhub-0.1.5.dist-info → cortexhub-0.1.8.dist-info}/METADATA +1 -1
- {cortexhub-0.1.5.dist-info → cortexhub-0.1.8.dist-info}/RECORD +12 -12
- {cortexhub-0.1.5.dist-info → cortexhub-0.1.8.dist-info}/WHEEL +0 -0
- {cortexhub-0.1.5.dist-info → cortexhub-0.1.8.dist-info}/licenses/LICENSE +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):
|
|
@@ -123,6 +116,14 @@ class ClaudeAgentsAdapter(ToolAdapter):
|
|
|
123
116
|
original_handler = original_decorated.handler
|
|
124
117
|
tool_name = original_decorated.name
|
|
125
118
|
tool_description = original_decorated.description
|
|
119
|
+
parameters_schema = None
|
|
120
|
+
if isinstance(input_schema, dict):
|
|
121
|
+
parameters_schema = input_schema
|
|
122
|
+
elif hasattr(input_schema, "model_json_schema"):
|
|
123
|
+
try:
|
|
124
|
+
parameters_schema = input_schema.model_json_schema()
|
|
125
|
+
except Exception:
|
|
126
|
+
parameters_schema = None
|
|
126
127
|
|
|
127
128
|
@wraps(original_handler)
|
|
128
129
|
async def governed_handler(args: dict[str, Any]) -> dict[str, Any]:
|
|
@@ -131,6 +132,7 @@ class ClaudeAgentsAdapter(ToolAdapter):
|
|
|
131
132
|
"name": tool_name,
|
|
132
133
|
"description": tool_description,
|
|
133
134
|
"framework": "claude_agents",
|
|
135
|
+
"parameters_schema": parameters_schema,
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
governed_fn = govern_execution(
|
cortexhub/adapters/crewai.py
CHANGED
|
@@ -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):
|
cortexhub/adapters/langgraph.py
CHANGED
|
@@ -93,6 +93,7 @@ class LangGraphAdapter(ToolAdapter):
|
|
|
93
93
|
"""Governed tool invocation."""
|
|
94
94
|
tool_name = getattr(self, "name", "unknown_tool")
|
|
95
95
|
tool_description = getattr(self, "description", None)
|
|
96
|
+
parameters_schema = adapter._extract_parameters_schema(self)
|
|
96
97
|
|
|
97
98
|
# Extract args - preserve structure without rewriting
|
|
98
99
|
if isinstance(input, dict):
|
|
@@ -109,6 +110,7 @@ class LangGraphAdapter(ToolAdapter):
|
|
|
109
110
|
"name": tool_name,
|
|
110
111
|
"description": tool_description,
|
|
111
112
|
"framework": "langgraph",
|
|
113
|
+
"parameters_schema": parameters_schema,
|
|
112
114
|
}
|
|
113
115
|
governed_fn = govern_execution(
|
|
114
116
|
tool_fn=lambda *a, **kw: tool_original_invoke(
|
|
@@ -411,12 +413,6 @@ class LangGraphAdapter(ToolAdapter):
|
|
|
411
413
|
name = tool.get("name") or "unknown_tool"
|
|
412
414
|
self._discovered_tools[name] = tool
|
|
413
415
|
|
|
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
416
|
def _normalize_tools(self, tools: Any) -> list[dict[str, Any]]:
|
|
421
417
|
"""Convert tool objects to inventory payloads."""
|
|
422
418
|
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):
|
|
@@ -109,6 +102,7 @@ class OpenAIAgentsAdapter(ToolAdapter):
|
|
|
109
102
|
original_invoke = tool.on_invoke_tool
|
|
110
103
|
tool_name = tool.name
|
|
111
104
|
tool_description = tool.description
|
|
105
|
+
parameters_schema = tool.params_json_schema or tool.strict_json_schema
|
|
112
106
|
|
|
113
107
|
async def governed_invoke(ctx, input_json: str) -> Any:
|
|
114
108
|
"""Governed tool invocation."""
|
|
@@ -121,6 +115,7 @@ class OpenAIAgentsAdapter(ToolAdapter):
|
|
|
121
115
|
"name": tool_name,
|
|
122
116
|
"description": tool_description,
|
|
123
117
|
"framework": "openai_agents",
|
|
118
|
+
"parameters_schema": parameters_schema,
|
|
124
119
|
}
|
|
125
120
|
|
|
126
121
|
# Create governed function
|
cortexhub/backend/client.py
CHANGED
|
@@ -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
|
*,
|
cortexhub/client.py
CHANGED
|
@@ -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(
|
|
@@ -439,6 +439,7 @@ class CortexHub:
|
|
|
439
439
|
framework: str,
|
|
440
440
|
call_original: Callable[[], Any],
|
|
441
441
|
tool_description: str | None = None,
|
|
442
|
+
parameters_schema: dict[str, Any] | None = None,
|
|
442
443
|
principal: Principal | dict[str, str] | None = None,
|
|
443
444
|
resource_type: str = "Tool",
|
|
444
445
|
) -> Any:
|
|
@@ -475,6 +476,10 @@ class CortexHub:
|
|
|
475
476
|
PolicyViolationError: If policy denies
|
|
476
477
|
ApprovalDeniedError: If approval denied
|
|
477
478
|
"""
|
|
479
|
+
expected_types = self._extract_expected_arg_types(parameters_schema)
|
|
480
|
+
|
|
481
|
+
expected_types = self._extract_expected_arg_types(parameters_schema)
|
|
482
|
+
|
|
478
483
|
# Step 1: Build request (structured, NOT flattened)
|
|
479
484
|
policy_args = self._sanitize_policy_args(args)
|
|
480
485
|
request = self.build_request(
|
|
@@ -515,6 +520,21 @@ class CortexHub:
|
|
|
515
520
|
span.set_attribute("cortexhub.raw.args", json.dumps(args, default=str))
|
|
516
521
|
|
|
517
522
|
try:
|
|
523
|
+
if expected_types and self.enforce and self.evaluator:
|
|
524
|
+
mismatches = self._validate_arg_types(args, expected_types)
|
|
525
|
+
if mismatches:
|
|
526
|
+
message = f"Tool argument type mismatch: {'; '.join(mismatches)}"
|
|
527
|
+
span.add_event(
|
|
528
|
+
"policy.decision",
|
|
529
|
+
attributes={
|
|
530
|
+
"decision.effect": "deny",
|
|
531
|
+
"decision.policy_id": "",
|
|
532
|
+
"decision.reasoning": message,
|
|
533
|
+
"decision.policy_name": "type_mismatch",
|
|
534
|
+
},
|
|
535
|
+
)
|
|
536
|
+
span.set_status(Status(StatusCode.ERROR, message))
|
|
537
|
+
raise PolicyViolationError(message, reasoning=message)
|
|
518
538
|
# Step 4: Policy evaluation (enforcement mode only)
|
|
519
539
|
if self.enforce and self.evaluator:
|
|
520
540
|
if os.getenv("CORTEXHUB_DEBUG_POLICY", "").lower() in ("1", "true", "yes"):
|
|
@@ -636,6 +656,7 @@ class CortexHub:
|
|
|
636
656
|
framework: str,
|
|
637
657
|
call_original: Callable[[], Any],
|
|
638
658
|
tool_description: str | None = None,
|
|
659
|
+
parameters_schema: dict[str, Any] | None = None,
|
|
639
660
|
principal: Principal | dict[str, str] | None = None,
|
|
640
661
|
resource_type: str = "Tool",
|
|
641
662
|
) -> Any:
|
|
@@ -684,6 +705,21 @@ class CortexHub:
|
|
|
684
705
|
span.set_attribute("cortexhub.raw.args", json.dumps(args, default=str))
|
|
685
706
|
|
|
686
707
|
try:
|
|
708
|
+
if expected_types and self.enforce and self.evaluator:
|
|
709
|
+
mismatches = self._validate_arg_types(args, expected_types)
|
|
710
|
+
if mismatches:
|
|
711
|
+
message = f"Tool argument type mismatch: {'; '.join(mismatches)}"
|
|
712
|
+
span.add_event(
|
|
713
|
+
"policy.decision",
|
|
714
|
+
attributes={
|
|
715
|
+
"decision.effect": "deny",
|
|
716
|
+
"decision.policy_id": "",
|
|
717
|
+
"decision.reasoning": message,
|
|
718
|
+
"decision.policy_name": "type_mismatch",
|
|
719
|
+
},
|
|
720
|
+
)
|
|
721
|
+
span.set_status(Status(StatusCode.ERROR, message))
|
|
722
|
+
raise PolicyViolationError(message, reasoning=message)
|
|
687
723
|
# Step 4: Policy evaluation (enforcement mode only)
|
|
688
724
|
if self.enforce and self.evaluator:
|
|
689
725
|
decision = self.evaluator.evaluate(request)
|
|
@@ -1316,6 +1352,49 @@ class CortexHub:
|
|
|
1316
1352
|
return "string"
|
|
1317
1353
|
return "unknown"
|
|
1318
1354
|
|
|
1355
|
+
def _extract_expected_arg_types(self, parameters_schema: dict[str, Any] | None) -> dict[str, str]:
|
|
1356
|
+
if not parameters_schema or not isinstance(parameters_schema, dict):
|
|
1357
|
+
return {}
|
|
1358
|
+
properties = parameters_schema.get("properties")
|
|
1359
|
+
if not isinstance(properties, dict):
|
|
1360
|
+
return {}
|
|
1361
|
+
expected: dict[str, str] = {}
|
|
1362
|
+
for name, schema in properties.items():
|
|
1363
|
+
if not isinstance(schema, dict):
|
|
1364
|
+
continue
|
|
1365
|
+
raw_type = schema.get("type")
|
|
1366
|
+
if isinstance(raw_type, list):
|
|
1367
|
+
raw_type = next((t for t in raw_type if t != "null"), None)
|
|
1368
|
+
if not isinstance(raw_type, str):
|
|
1369
|
+
continue
|
|
1370
|
+
normalized = raw_type.lower()
|
|
1371
|
+
if normalized == "integer":
|
|
1372
|
+
normalized = "number"
|
|
1373
|
+
if normalized in ("number", "string", "boolean"):
|
|
1374
|
+
expected[str(name)] = normalized
|
|
1375
|
+
return expected
|
|
1376
|
+
|
|
1377
|
+
def _validate_arg_types(self, args: dict[str, Any], expected_types: dict[str, str]) -> list[str]:
|
|
1378
|
+
if not isinstance(args, dict):
|
|
1379
|
+
return []
|
|
1380
|
+
mismatches: list[str] = []
|
|
1381
|
+
for name, expected in expected_types.items():
|
|
1382
|
+
if name not in args:
|
|
1383
|
+
continue
|
|
1384
|
+
value = args.get(name)
|
|
1385
|
+
if value is None:
|
|
1386
|
+
continue
|
|
1387
|
+
if expected == "number":
|
|
1388
|
+
if not isinstance(value, int) or isinstance(value, bool):
|
|
1389
|
+
mismatches.append(f"{name} expected number but got {type(value).__name__}")
|
|
1390
|
+
elif expected == "string":
|
|
1391
|
+
if not isinstance(value, str):
|
|
1392
|
+
mismatches.append(f"{name} expected string but got {type(value).__name__}")
|
|
1393
|
+
elif expected == "boolean":
|
|
1394
|
+
if not isinstance(value, bool):
|
|
1395
|
+
mismatches.append(f"{name} expected boolean but got {type(value).__name__}")
|
|
1396
|
+
return mismatches
|
|
1397
|
+
|
|
1319
1398
|
def trace_llm_call(
|
|
1320
1399
|
self,
|
|
1321
1400
|
model: str,
|
|
@@ -1785,25 +1864,6 @@ class CortexHub:
|
|
|
1785
1864
|
if not isinstance(cleaned_args, dict):
|
|
1786
1865
|
return {}
|
|
1787
1866
|
|
|
1788
|
-
if "amount" in cleaned_args:
|
|
1789
|
-
from decimal import Decimal, InvalidOperation
|
|
1790
|
-
|
|
1791
|
-
amount = cleaned_args.get("amount")
|
|
1792
|
-
dec_amount: Decimal | None = None
|
|
1793
|
-
if isinstance(amount, int):
|
|
1794
|
-
dec_amount = Decimal(amount)
|
|
1795
|
-
elif isinstance(amount, str):
|
|
1796
|
-
try:
|
|
1797
|
-
dec_amount = Decimal(amount)
|
|
1798
|
-
except InvalidOperation:
|
|
1799
|
-
dec_amount = None
|
|
1800
|
-
if dec_amount is not None:
|
|
1801
|
-
quantized = dec_amount.quantize(Decimal("0.01"))
|
|
1802
|
-
if quantized == dec_amount:
|
|
1803
|
-
cleaned_args["amount_cents"] = int(
|
|
1804
|
-
(quantized * 100).to_integral_value()
|
|
1805
|
-
)
|
|
1806
|
-
|
|
1807
1867
|
return cleaned_args
|
|
1808
1868
|
|
|
1809
1869
|
def _summarize_policy_args(self, args: dict[str, Any]) -> dict[str, Any]:
|
cortexhub/pipeline.py
CHANGED
|
@@ -46,6 +46,12 @@ def govern_execution(
|
|
|
46
46
|
framework = tool_metadata.get("framework", "unknown")
|
|
47
47
|
model = tool_metadata.get("model", "unknown")
|
|
48
48
|
prompt = tool_metadata.get("prompt")
|
|
49
|
+
parameters_schema = (
|
|
50
|
+
tool_metadata.get("parameters_schema")
|
|
51
|
+
or tool_metadata.get("params_json_schema")
|
|
52
|
+
or tool_metadata.get("input_schema")
|
|
53
|
+
or tool_metadata.get("strict_json_schema")
|
|
54
|
+
)
|
|
49
55
|
call_original = tool_metadata.get("call_original")
|
|
50
56
|
if call_original is None:
|
|
51
57
|
call_original = tool_fn
|
|
@@ -78,6 +84,7 @@ def govern_execution(
|
|
|
78
84
|
args=kwargs, # Use kwargs for structured arguments
|
|
79
85
|
framework=framework,
|
|
80
86
|
call_original=lambda: tool_fn(*args, **kwargs),
|
|
87
|
+
parameters_schema=parameters_schema,
|
|
81
88
|
)
|
|
82
89
|
return async_wrapper
|
|
83
90
|
else:
|
|
@@ -88,5 +95,6 @@ def govern_execution(
|
|
|
88
95
|
args=kwargs, # Use kwargs for structured arguments
|
|
89
96
|
framework=framework,
|
|
90
97
|
call_original=lambda: tool_fn(*args, **kwargs),
|
|
98
|
+
parameters_schema=parameters_schema,
|
|
91
99
|
)
|
|
92
100
|
return sync_wrapper
|
cortexhub/version.py
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
cortexhub/__init__.py,sha256=hnwsiUy5BT3QaPNK5yXqex6zRzZlok43S04y-dkNWSE,4376
|
|
2
2
|
cortexhub/auto_protect.py,sha256=yW-iW9cdGg-fM8EtR_Z9UkMczn51U8BKh5pOBgV1VqE,3951
|
|
3
|
-
cortexhub/client.py,sha256=
|
|
3
|
+
cortexhub/client.py,sha256=R2lxM2E4NAYeIo013TYcVZiuYrfXm1KBeP-17hinLgM,100212
|
|
4
4
|
cortexhub/config.py,sha256=kpwVMTRcSisJy8HHBL3ZBeQoMN3lE7zziRzEYaq92LI,941
|
|
5
5
|
cortexhub/errors.py,sha256=hsknLHaVCqk5MkpXvahxYIUshDt2VGZfbBWRronFvVM,3697
|
|
6
6
|
cortexhub/frameworks.py,sha256=WCPokPRVafLqe73MDbJasi8FyNHTM2T4wfaBg0LuWoM,2223
|
|
7
|
-
cortexhub/pipeline.py,sha256=
|
|
8
|
-
cortexhub/version.py,sha256=
|
|
7
|
+
cortexhub/pipeline.py,sha256=5HalesMHy-39KOPtPGidih3YSrX2Xsc_Se0C6CyBaIM,3588
|
|
8
|
+
cortexhub/version.py,sha256=5kkypMZTwNSkQR5pPfUn4kRFz3PtN8_HpqYKHbJkghg,68
|
|
9
9
|
cortexhub/adapters/__init__.py,sha256=Lb6RquGPGs4exdfSB6Qb6q6HyGczozuLWSaLCtgZdyo,130
|
|
10
10
|
cortexhub/adapters/base.py,sha256=_ODoJFLQLYnowse3MHQk8bN9KjE1oQr8QDNNlvPSwSs,4094
|
|
11
|
-
cortexhub/adapters/claude_agents.py,sha256=
|
|
12
|
-
cortexhub/adapters/crewai.py,sha256
|
|
13
|
-
cortexhub/adapters/langgraph.py,sha256=
|
|
14
|
-
cortexhub/adapters/openai_agents.py,sha256=
|
|
11
|
+
cortexhub/adapters/claude_agents.py,sha256=aOCAje8Rpio6X_mmqka8mHwdw4Xtw0_yKAsLS7jebXw,23260
|
|
12
|
+
cortexhub/adapters/crewai.py,sha256=-8s27SU-_Z1c2D-jgVa1VfrtDbEDub3g6ahBcG5wy-U,24622
|
|
13
|
+
cortexhub/adapters/langgraph.py,sha256=zqE2WkzWRSvmUvqVagzfC83bR4ip6gvHBPZoiq8YEr4,20772
|
|
14
|
+
cortexhub/adapters/openai_agents.py,sha256=IIG894XH5T07gnfXbPg_oVGZYPBNXsQEakuAYugpn64,21393
|
|
15
15
|
cortexhub/audit/__init__.py,sha256=tKE9CdpAIpP04oeLOza96jwZs4er5G5bRBWGibvh4Xw,545
|
|
16
16
|
cortexhub/audit/events.py,sha256=w1uHbYzwBTDRm8gKAY_TQlXHjUj2nZt-iXk0NcqzRak,5965
|
|
17
17
|
cortexhub/backend/__init__.py,sha256=Yt5fcaW24l6YwPCLvKbcKAXhhrWTUjwgqJsLOIzgIAo,133
|
|
18
|
-
cortexhub/backend/client.py,sha256=
|
|
18
|
+
cortexhub/backend/client.py,sha256=542TKmKoGCOG54RdFLj4ur675LOxwhACFmtCFQ4eWgw,15310
|
|
19
19
|
cortexhub/context/__init__.py,sha256=BWoR2s4ogOs1YXPFBO7e8_UOZ_5AWYfMlv5PTVORN2Y,144
|
|
20
20
|
cortexhub/context/enricher.py,sha256=cComyfE10EbaCAI8KLM0ED6j-wKYBc26MRnIn-dxhmU,5322
|
|
21
21
|
cortexhub/guardrails/__init__.py,sha256=RH1u8w3FFLd6u7-OYgj42PqAJO9jXsl8-tcLiL24uOo,103
|
|
@@ -33,7 +33,7 @@ cortexhub/policy/models.py,sha256=81NPX36yru0AZ22Wivytv3uxlwir4VsTN4MZgq4bdiA,38
|
|
|
33
33
|
cortexhub/policy/sync.py,sha256=7kAc3rd5WftipR8XKwvU8SwukIoY-0gcGW2fsf-ij_I,5999
|
|
34
34
|
cortexhub/telemetry/__init__.py,sha256=RSY38hHnYtbRURLoWAhbYYxYMtCItVYZBNN6Bfny8uA,1049
|
|
35
35
|
cortexhub/telemetry/otel.py,sha256=T2pC-K_S_KmrLvfcd3oHMbEwC5ibGZ-PXTZSY0xJgcQ,16633
|
|
36
|
-
cortexhub-0.1.
|
|
37
|
-
cortexhub-0.1.
|
|
38
|
-
cortexhub-0.1.
|
|
39
|
-
cortexhub-0.1.
|
|
36
|
+
cortexhub-0.1.8.dist-info/METADATA,sha256=wTMMUuiZkpi_yo269xZftwKVta7yYChZ5OczmAc1NpE,8539
|
|
37
|
+
cortexhub-0.1.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
38
|
+
cortexhub-0.1.8.dist-info/licenses/LICENSE,sha256=R-lPsEVN69q2o19ge2_O9Vt9cJuGM557oEYX3XdnvIk,1066
|
|
39
|
+
cortexhub-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|