agent_os_kernel 3.1.0__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.
- agent_control_plane/__init__.py +662 -0
- agent_control_plane/a2a_adapter.py +543 -0
- agent_control_plane/adapter.py +417 -0
- agent_control_plane/agent_hibernation.py +394 -0
- agent_control_plane/agent_kernel.py +470 -0
- agent_control_plane/compliance.py +720 -0
- agent_control_plane/constraint_graphs.py +478 -0
- agent_control_plane/control_plane.py +854 -0
- agent_control_plane/example_executors.py +195 -0
- agent_control_plane/execution_engine.py +231 -0
- agent_control_plane/flight_recorder.py +846 -0
- agent_control_plane/governance_layer.py +435 -0
- agent_control_plane/hf_utils.py +563 -0
- agent_control_plane/interfaces/__init__.py +55 -0
- agent_control_plane/interfaces/kernel_interface.py +361 -0
- agent_control_plane/interfaces/plugin_interface.py +497 -0
- agent_control_plane/interfaces/protocol_interfaces.py +387 -0
- agent_control_plane/kernel_space.py +1009 -0
- agent_control_plane/langchain_adapter.py +424 -0
- agent_control_plane/lifecycle.py +3113 -0
- agent_control_plane/mcp_adapter.py +653 -0
- agent_control_plane/ml_safety.py +563 -0
- agent_control_plane/multimodal.py +727 -0
- agent_control_plane/mute_agent.py +422 -0
- agent_control_plane/observability.py +787 -0
- agent_control_plane/orchestrator.py +482 -0
- agent_control_plane/plugin_registry.py +750 -0
- agent_control_plane/policy_engine.py +954 -0
- agent_control_plane/process_isolation.py +777 -0
- agent_control_plane/shadow_mode.py +310 -0
- agent_control_plane/signals.py +493 -0
- agent_control_plane/supervisor_agents.py +430 -0
- agent_control_plane/time_travel_debugger.py +557 -0
- agent_control_plane/tool_registry.py +452 -0
- agent_control_plane/vfs.py +697 -0
- agent_kernel/__init__.py +69 -0
- agent_kernel/analyzer.py +435 -0
- agent_kernel/auditor.py +36 -0
- agent_kernel/completeness_auditor.py +237 -0
- agent_kernel/detector.py +203 -0
- agent_kernel/kernel.py +744 -0
- agent_kernel/memory_manager.py +85 -0
- agent_kernel/models.py +374 -0
- agent_kernel/nudge_mechanism.py +263 -0
- agent_kernel/outcome_analyzer.py +338 -0
- agent_kernel/patcher.py +582 -0
- agent_kernel/semantic_analyzer.py +316 -0
- agent_kernel/semantic_purge.py +349 -0
- agent_kernel/simulator.py +449 -0
- agent_kernel/teacher.py +85 -0
- agent_kernel/triage.py +152 -0
- agent_os/__init__.py +409 -0
- agent_os/_adversarial_impl.py +200 -0
- agent_os/_circuit_breaker_impl.py +232 -0
- agent_os/_mcp_metrics.py +193 -0
- agent_os/adversarial.py +20 -0
- agent_os/agents_compat.py +490 -0
- agent_os/audit_logger.py +135 -0
- agent_os/base_agent.py +651 -0
- agent_os/circuit_breaker.py +34 -0
- agent_os/cli/__init__.py +659 -0
- agent_os/cli/cmd_audit.py +128 -0
- agent_os/cli/cmd_init.py +152 -0
- agent_os/cli/cmd_policy.py +41 -0
- agent_os/cli/cmd_policy_gen.py +180 -0
- agent_os/cli/cmd_validate.py +258 -0
- agent_os/cli/mcp_scan.py +265 -0
- agent_os/cli/output.py +192 -0
- agent_os/cli/policy_checker.py +330 -0
- agent_os/compat.py +74 -0
- agent_os/constraint_graph.py +234 -0
- agent_os/content_governance.py +140 -0
- agent_os/context_budget.py +305 -0
- agent_os/credential_redactor.py +224 -0
- agent_os/diff_policy.py +89 -0
- agent_os/egress_policy.py +159 -0
- agent_os/escalation.py +276 -0
- agent_os/event_bus.py +124 -0
- agent_os/exceptions.py +180 -0
- agent_os/execution_context_policy.py +141 -0
- agent_os/github_enterprise.py +96 -0
- agent_os/health.py +20 -0
- agent_os/integrations/__init__.py +279 -0
- agent_os/integrations/a2a_adapter.py +279 -0
- agent_os/integrations/agent_lightning/__init__.py +30 -0
- agent_os/integrations/anthropic_adapter.py +420 -0
- agent_os/integrations/autogen_adapter.py +620 -0
- agent_os/integrations/base.py +1137 -0
- agent_os/integrations/compat.py +229 -0
- agent_os/integrations/config.py +98 -0
- agent_os/integrations/conversation_guardian.py +957 -0
- agent_os/integrations/crewai_adapter.py +467 -0
- agent_os/integrations/drift_detector.py +425 -0
- agent_os/integrations/dry_run.py +124 -0
- agent_os/integrations/escalation.py +582 -0
- agent_os/integrations/gemini_adapter.py +364 -0
- agent_os/integrations/google_adk_adapter.py +633 -0
- agent_os/integrations/guardrails_adapter.py +394 -0
- agent_os/integrations/health.py +197 -0
- agent_os/integrations/langchain_adapter.py +654 -0
- agent_os/integrations/llamafirewall.py +343 -0
- agent_os/integrations/llamaindex_adapter.py +188 -0
- agent_os/integrations/logging.py +191 -0
- agent_os/integrations/maf_adapter.py +631 -0
- agent_os/integrations/mistral_adapter.py +365 -0
- agent_os/integrations/openai_adapter.py +816 -0
- agent_os/integrations/openai_agents_sdk.py +406 -0
- agent_os/integrations/policy_compose.py +171 -0
- agent_os/integrations/profiling.py +144 -0
- agent_os/integrations/pydantic_ai_adapter.py +420 -0
- agent_os/integrations/rate_limiter.py +130 -0
- agent_os/integrations/rbac.py +143 -0
- agent_os/integrations/registry.py +113 -0
- agent_os/integrations/scope_guard.py +303 -0
- agent_os/integrations/semantic_kernel_adapter.py +769 -0
- agent_os/integrations/smolagents_adapter.py +629 -0
- agent_os/integrations/templates.py +178 -0
- agent_os/integrations/token_budget.py +134 -0
- agent_os/integrations/tool_aliases.py +190 -0
- agent_os/integrations/webhooks.py +177 -0
- agent_os/lite.py +208 -0
- agent_os/mcp_gateway.py +385 -0
- agent_os/mcp_message_signer.py +273 -0
- agent_os/mcp_protocols.py +161 -0
- agent_os/mcp_response_scanner.py +232 -0
- agent_os/mcp_security.py +924 -0
- agent_os/mcp_session_auth.py +231 -0
- agent_os/mcp_sliding_rate_limiter.py +184 -0
- agent_os/memory_guard.py +409 -0
- agent_os/metrics.py +134 -0
- agent_os/mute.py +428 -0
- agent_os/mute_agent.py +209 -0
- agent_os/policies/__init__.py +77 -0
- agent_os/policies/async_evaluator.py +275 -0
- agent_os/policies/backends.py +670 -0
- agent_os/policies/bridge.py +169 -0
- agent_os/policies/budget.py +85 -0
- agent_os/policies/cli.py +294 -0
- agent_os/policies/conflict_resolution.py +270 -0
- agent_os/policies/data_classification.py +252 -0
- agent_os/policies/evaluator.py +239 -0
- agent_os/policies/policy_schema.json +228 -0
- agent_os/policies/rate_limiting.py +145 -0
- agent_os/policies/schema.py +115 -0
- agent_os/policies/shared.py +331 -0
- agent_os/prompt_injection.py +694 -0
- agent_os/providers.py +182 -0
- agent_os/py.typed +0 -0
- agent_os/retry.py +81 -0
- agent_os/reversibility.py +251 -0
- agent_os/sandbox.py +432 -0
- agent_os/sandbox_provider.py +140 -0
- agent_os/secure_codegen.py +525 -0
- agent_os/security_skills.py +538 -0
- agent_os/semantic_policy.py +422 -0
- agent_os/server/__init__.py +15 -0
- agent_os/server/__main__.py +25 -0
- agent_os/server/app.py +277 -0
- agent_os/server/models.py +104 -0
- agent_os/shift_left_metrics.py +130 -0
- agent_os/stateless.py +742 -0
- agent_os/supervisor.py +148 -0
- agent_os/task_outcome.py +148 -0
- agent_os/transparency.py +181 -0
- agent_os/trust_root.py +128 -0
- agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
- agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
- agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
- agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
- agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
- agent_os_observability/__init__.py +27 -0
- agent_os_observability/dashboards.py +898 -0
- agent_os_observability/metrics.py +398 -0
- agent_os_observability/server.py +223 -0
- agent_os_observability/tracer.py +232 -0
- agent_primitives/__init__.py +24 -0
- agent_primitives/failures.py +84 -0
- agent_primitives/py.typed +0 -0
- amb_core/__init__.py +177 -0
- amb_core/adapters/__init__.py +57 -0
- amb_core/adapters/aws_sqs_broker.py +376 -0
- amb_core/adapters/azure_servicebus_broker.py +340 -0
- amb_core/adapters/kafka_broker.py +260 -0
- amb_core/adapters/nats_broker.py +285 -0
- amb_core/adapters/rabbitmq_broker.py +235 -0
- amb_core/adapters/redis_broker.py +262 -0
- amb_core/broker.py +145 -0
- amb_core/bus.py +481 -0
- amb_core/cloudevents.py +509 -0
- amb_core/dlq.py +345 -0
- amb_core/hf_utils.py +536 -0
- amb_core/memory_broker.py +410 -0
- amb_core/models.py +141 -0
- amb_core/persistence.py +529 -0
- amb_core/schema.py +294 -0
- amb_core/tracing.py +358 -0
- atr/__init__.py +640 -0
- atr/access.py +348 -0
- atr/composition.py +645 -0
- atr/decorator.py +357 -0
- atr/executor.py +384 -0
- atr/health.py +557 -0
- atr/hf_utils.py +449 -0
- atr/injection.py +422 -0
- atr/metrics.py +440 -0
- atr/policies.py +403 -0
- atr/py.typed +2 -0
- atr/registry.py +452 -0
- atr/schema.py +480 -0
- atr/tools/safe/__init__.py +75 -0
- atr/tools/safe/calculator.py +467 -0
- atr/tools/safe/datetime_tool.py +443 -0
- atr/tools/safe/file_reader.py +402 -0
- atr/tools/safe/http_client.py +316 -0
- atr/tools/safe/json_parser.py +374 -0
- atr/tools/safe/text_tool.py +537 -0
- atr/tools/safe/toolkit.py +175 -0
- caas/__init__.py +162 -0
- caas/api/__init__.py +7 -0
- caas/api/server.py +1328 -0
- caas/caching.py +834 -0
- caas/cli.py +210 -0
- caas/conversation.py +223 -0
- caas/decay.py +72 -0
- caas/detection/__init__.py +9 -0
- caas/detection/detector.py +238 -0
- caas/enrichment.py +130 -0
- caas/gateway/__init__.py +27 -0
- caas/gateway/trust_gateway.py +474 -0
- caas/hf_utils.py +479 -0
- caas/ingestion/__init__.py +23 -0
- caas/ingestion/processors.py +253 -0
- caas/ingestion/structure_parser.py +188 -0
- caas/models.py +356 -0
- caas/pragmatic_truth.py +444 -0
- caas/routing/__init__.py +10 -0
- caas/routing/heuristic_router.py +58 -0
- caas/storage/__init__.py +9 -0
- caas/storage/store.py +389 -0
- caas/triad.py +213 -0
- caas/tuning/__init__.py +9 -0
- caas/tuning/tuner.py +329 -0
- caas/vfs/__init__.py +14 -0
- caas/vfs/filesystem.py +452 -0
- cmvk/__init__.py +218 -0
- cmvk/audit.py +402 -0
- cmvk/benchmarks.py +478 -0
- cmvk/constitutional.py +904 -0
- cmvk/hf_utils.py +301 -0
- cmvk/metrics.py +473 -0
- cmvk/profiles.py +300 -0
- cmvk/py.typed +0 -0
- cmvk/types.py +12 -0
- cmvk/verification.py +956 -0
- emk/__init__.py +89 -0
- emk/causal.py +352 -0
- emk/hf_utils.py +421 -0
- emk/indexer.py +83 -0
- emk/py.typed +0 -0
- emk/schema.py +204 -0
- emk/sleep_cycle.py +347 -0
- emk/store.py +281 -0
- iatp/__init__.py +166 -0
- iatp/attestation.py +461 -0
- iatp/cli.py +317 -0
- iatp/hf_utils.py +472 -0
- iatp/ipc_pipes.py +580 -0
- iatp/main.py +412 -0
- iatp/models/__init__.py +447 -0
- iatp/policy_engine.py +337 -0
- iatp/py.typed +2 -0
- iatp/recovery.py +321 -0
- iatp/security/__init__.py +270 -0
- iatp/sidecar/__init__.py +519 -0
- iatp/telemetry/__init__.py +164 -0
- iatp/tests/__init__.py +1 -0
- iatp/tests/test_attestation.py +370 -0
- iatp/tests/test_cli.py +131 -0
- iatp/tests/test_ed25519_attestation.py +211 -0
- iatp/tests/test_models.py +130 -0
- iatp/tests/test_policy_engine.py +347 -0
- iatp/tests/test_recovery.py +281 -0
- iatp/tests/test_security.py +222 -0
- iatp/tests/test_sidecar.py +167 -0
- iatp/tests/test_telemetry.py +175 -0
- mcp_kernel_server/__init__.py +28 -0
- mcp_kernel_server/cli.py +274 -0
- mcp_kernel_server/resources.py +217 -0
- mcp_kernel_server/server.py +564 -0
- mcp_kernel_server/tools.py +1174 -0
- mute_agent/__init__.py +68 -0
- mute_agent/core/__init__.py +1 -0
- mute_agent/core/execution_agent.py +166 -0
- mute_agent/core/handshake_protocol.py +201 -0
- mute_agent/core/reasoning_agent.py +238 -0
- mute_agent/knowledge_graph/__init__.py +1 -0
- mute_agent/knowledge_graph/graph_elements.py +65 -0
- mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
- mute_agent/knowledge_graph/subgraph.py +224 -0
- mute_agent/listener/__init__.py +43 -0
- mute_agent/listener/adapters/__init__.py +31 -0
- mute_agent/listener/adapters/base_adapter.py +189 -0
- mute_agent/listener/adapters/caas_adapter.py +344 -0
- mute_agent/listener/adapters/control_plane_adapter.py +436 -0
- mute_agent/listener/adapters/iatp_adapter.py +332 -0
- mute_agent/listener/adapters/scak_adapter.py +251 -0
- mute_agent/listener/listener.py +610 -0
- mute_agent/listener/state_observer.py +436 -0
- mute_agent/listener/threshold_config.py +313 -0
- mute_agent/super_system/__init__.py +1 -0
- mute_agent/super_system/router.py +204 -0
- mute_agent/visualization/__init__.py +10 -0
- mute_agent/visualization/graph_debugger.py +502 -0
- nexus/README.md +60 -0
- nexus/__init__.py +51 -0
- nexus/arbiter.py +359 -0
- nexus/client.py +466 -0
- nexus/dmz.py +444 -0
- nexus/escrow.py +430 -0
- nexus/exceptions.py +286 -0
- nexus/pyproject.toml +36 -0
- nexus/registry.py +393 -0
- nexus/reputation.py +425 -0
- nexus/schemas/__init__.py +51 -0
- nexus/schemas/compliance.py +276 -0
- nexus/schemas/escrow.py +251 -0
- nexus/schemas/manifest.py +225 -0
- nexus/schemas/receipt.py +208 -0
- nexus/tests/__init__.py +0 -0
- nexus/tests/conftest.py +146 -0
- nexus/tests/test_arbiter.py +192 -0
- nexus/tests/test_dmz.py +194 -0
- nexus/tests/test_escrow.py +276 -0
- nexus/tests/test_exceptions.py +225 -0
- nexus/tests/test_registry.py +232 -0
- nexus/tests/test_reputation.py +328 -0
- nexus/tests/test_schemas.py +295 -0
iatp/cli.py
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
IATP CLI - Command Line Interface for Inter-Agent Trust Protocol
|
|
5
|
+
|
|
6
|
+
Provides developer tools to:
|
|
7
|
+
- Validate capability_manifest.json files
|
|
8
|
+
- Scan agents for trust scores
|
|
9
|
+
- Test IATP configurations
|
|
10
|
+
"""
|
|
11
|
+
import json
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
import httpx
|
|
16
|
+
|
|
17
|
+
from iatp import __version__
|
|
18
|
+
from iatp.models import CapabilityManifest, RetentionPolicy, ReversibilityLevel, TrustLevel
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.group()
|
|
22
|
+
@click.version_option(version=__version__, prog_name="iatp")
|
|
23
|
+
def cli():
|
|
24
|
+
"""
|
|
25
|
+
IATP CLI - Inter-Agent Trust Protocol Developer Tools
|
|
26
|
+
|
|
27
|
+
Validate manifests, scan agents, and test trust configurations.
|
|
28
|
+
"""
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@cli.command()
|
|
33
|
+
@click.argument('manifest_path', type=click.Path(exists=True))
|
|
34
|
+
@click.option('--verbose', '-v', is_flag=True, help='Show detailed validation output')
|
|
35
|
+
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
|
|
36
|
+
def verify(manifest_path: str, verbose: bool, output_json: bool):
|
|
37
|
+
"""
|
|
38
|
+
Validate a capability_manifest.json file.
|
|
39
|
+
|
|
40
|
+
Checks for:
|
|
41
|
+
- Valid JSON schema
|
|
42
|
+
- Logical contradictions (e.g., retention: forever + privacy: strict)
|
|
43
|
+
- Required fields
|
|
44
|
+
- Enum value validity
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
iatp verify ./manifest.json
|
|
48
|
+
"""
|
|
49
|
+
if not output_json:
|
|
50
|
+
click.echo(f"š Validating manifest: {manifest_path}")
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# Load the manifest file
|
|
54
|
+
with open(manifest_path) as f:
|
|
55
|
+
manifest_data = json.load(f)
|
|
56
|
+
|
|
57
|
+
# Validate using Pydantic model
|
|
58
|
+
try:
|
|
59
|
+
manifest = CapabilityManifest(**manifest_data)
|
|
60
|
+
except (ValueError, KeyError, PermissionError) as e:
|
|
61
|
+
err_msg = "Manifest validation failed due to invalid schema or format."
|
|
62
|
+
if output_json:
|
|
63
|
+
print(json.dumps({"status": "fail", "error": err_msg, "type": "ValidationError"}, indent=2))
|
|
64
|
+
else:
|
|
65
|
+
click.echo("\nā Validation failed:", err=True)
|
|
66
|
+
click.echo(f" {err_msg}", err=True)
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
except Exception:
|
|
69
|
+
err_msg = "An internal error occurred while validating the manifest."
|
|
70
|
+
if output_json:
|
|
71
|
+
print(json.dumps({"status": "fail", "error": err_msg, "type": "InternalError"}, indent=2))
|
|
72
|
+
else:
|
|
73
|
+
click.echo(f"\nā Error: {err_msg}", err=True)
|
|
74
|
+
sys.exit(1)
|
|
75
|
+
|
|
76
|
+
# Perform logical contradiction checks
|
|
77
|
+
errors = []
|
|
78
|
+
warnings = []
|
|
79
|
+
|
|
80
|
+
# Check 1: Retention policy vs. privacy expectations
|
|
81
|
+
if manifest.privacy_contract.retention == RetentionPolicy.PERMANENT:
|
|
82
|
+
if manifest.trust_level in [TrustLevel.VERIFIED_PARTNER, TrustLevel.STANDARD]:
|
|
83
|
+
warnings.append(
|
|
84
|
+
"ā ļø Permanent retention with trusted agent - consider ephemeral or temporary"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Check 2: Reversibility vs. trust level
|
|
88
|
+
if manifest.capabilities.reversibility == ReversibilityLevel.NONE:
|
|
89
|
+
if manifest.trust_level == TrustLevel.UNTRUSTED:
|
|
90
|
+
errors.append(
|
|
91
|
+
"ā Untrusted agent with no reversibility is a high-risk configuration"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Check 3: Human review with high trust
|
|
95
|
+
if manifest.privacy_contract.human_review:
|
|
96
|
+
if manifest.trust_level == TrustLevel.VERIFIED_PARTNER:
|
|
97
|
+
warnings.append(
|
|
98
|
+
"ā ļø Human review enabled for verified partner - may not be necessary"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Calculate trust score
|
|
102
|
+
trust_score = manifest.calculate_trust_score()
|
|
103
|
+
|
|
104
|
+
if output_json:
|
|
105
|
+
print(json.dumps({
|
|
106
|
+
"status": "fail" if errors else "success",
|
|
107
|
+
"agent_id": manifest.agent_id,
|
|
108
|
+
"trust_level": manifest.trust_level.value,
|
|
109
|
+
"trust_score": trust_score,
|
|
110
|
+
"errors": errors,
|
|
111
|
+
"warnings": warnings
|
|
112
|
+
}, indent=2))
|
|
113
|
+
else:
|
|
114
|
+
if verbose:
|
|
115
|
+
click.echo("\nš Raw manifest data:")
|
|
116
|
+
click.echo(json.dumps(manifest_data, indent=2))
|
|
117
|
+
|
|
118
|
+
# Display results
|
|
119
|
+
if errors:
|
|
120
|
+
click.echo(f"\nā Validation failed with {len(errors)} error(s):")
|
|
121
|
+
for error in errors:
|
|
122
|
+
click.echo(f" {error}")
|
|
123
|
+
sys.exit(1)
|
|
124
|
+
|
|
125
|
+
click.echo("\nā
Schema validation passed")
|
|
126
|
+
click.echo(f" Agent ID: {manifest.agent_id}")
|
|
127
|
+
click.echo(f" Trust Level: {manifest.trust_level.value}")
|
|
128
|
+
click.echo(f" Trust Score: {trust_score}/10")
|
|
129
|
+
|
|
130
|
+
if warnings:
|
|
131
|
+
click.echo(f"\nā ļø {len(warnings)} warning(s):")
|
|
132
|
+
for warning in warnings:
|
|
133
|
+
click.echo(f" {warning}")
|
|
134
|
+
|
|
135
|
+
if verbose:
|
|
136
|
+
click.echo("\nš Detailed Analysis:")
|
|
137
|
+
click.echo(f" Reversibility: {manifest.capabilities.reversibility.value}")
|
|
138
|
+
click.echo(f" Idempotency: {manifest.capabilities.idempotency}")
|
|
139
|
+
if manifest.capabilities.rate_limit:
|
|
140
|
+
click.echo(f" Rate Limit: {manifest.capabilities.rate_limit} req/min")
|
|
141
|
+
if manifest.capabilities.sla_latency:
|
|
142
|
+
click.echo(f" SLA Latency: {manifest.capabilities.sla_latency}")
|
|
143
|
+
if manifest.capabilities.undo_window:
|
|
144
|
+
click.echo(f" Undo Window: {manifest.capabilities.undo_window}")
|
|
145
|
+
click.echo(f" Retention: {manifest.privacy_contract.retention.value}")
|
|
146
|
+
click.echo(f" Human Review: {manifest.privacy_contract.human_review}")
|
|
147
|
+
|
|
148
|
+
click.echo("\n⨠Manifest is valid and ready to use!")
|
|
149
|
+
|
|
150
|
+
except FileNotFoundError:
|
|
151
|
+
if output_json:
|
|
152
|
+
print(json.dumps({"status": "fail", "error": f"File not found: {manifest_path}"}, indent=2))
|
|
153
|
+
else:
|
|
154
|
+
click.echo(f"ā File not found: {manifest_path}", err=True)
|
|
155
|
+
sys.exit(1)
|
|
156
|
+
except json.JSONDecodeError as e:
|
|
157
|
+
err_msg = "Invalid JSON structure provided."
|
|
158
|
+
if output_json:
|
|
159
|
+
print(json.dumps({"status": "fail", "error": err_msg}, indent=2))
|
|
160
|
+
else:
|
|
161
|
+
click.echo(f"ā {err_msg}", err=True)
|
|
162
|
+
sys.exit(1)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
# Sanitize exception message to avoid leaking internal details
|
|
165
|
+
is_known = isinstance(e, (FileNotFoundError, json.JSONDecodeError, ValueError, PermissionError))
|
|
166
|
+
error_msg = "A validation or file access error occurred." if is_known else "An internal error occurred during verification."
|
|
167
|
+
|
|
168
|
+
if output_json:
|
|
169
|
+
print(json.dumps({
|
|
170
|
+
"status": "fail",
|
|
171
|
+
"error": error_msg,
|
|
172
|
+
"type": "DataValidationError" if is_known else "InternalError"
|
|
173
|
+
}, indent=2))
|
|
174
|
+
else:
|
|
175
|
+
click.echo(f"ā Error: {error_msg}", err=True)
|
|
176
|
+
sys.exit(1)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@cli.command()
|
|
180
|
+
@click.argument('agent_url')
|
|
181
|
+
@click.option('--timeout', '-t', default=10, help='Request timeout in seconds')
|
|
182
|
+
@click.option('--verbose', '-v', is_flag=True, help='Show detailed scan output')
|
|
183
|
+
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
|
|
184
|
+
def scan(agent_url: str, timeout: int, verbose: bool, output_json: bool):
|
|
185
|
+
"""
|
|
186
|
+
Scan an agent's capabilities endpoint and return a trust score.
|
|
187
|
+
|
|
188
|
+
Pings the agent's /.well-known/agent-manifest endpoint and
|
|
189
|
+
analyzes the exposed guarantees to calculate a trust score (0-100).
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
iatp scan http://localhost:8001
|
|
193
|
+
iatp scan https://api.example.com/agent --timeout 30
|
|
194
|
+
"""
|
|
195
|
+
if not output_json:
|
|
196
|
+
click.echo(f"š Scanning agent: {agent_url}")
|
|
197
|
+
|
|
198
|
+
# Ensure URL has scheme
|
|
199
|
+
if not agent_url.startswith(('http://', 'https://')):
|
|
200
|
+
agent_url = f"http://{agent_url}"
|
|
201
|
+
|
|
202
|
+
# Construct manifest endpoint URL
|
|
203
|
+
manifest_url = f"{agent_url.rstrip('/')}/.well-known/agent-manifest"
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
# Fetch the manifest
|
|
207
|
+
with httpx.Client(timeout=timeout) as client:
|
|
208
|
+
if verbose and not output_json:
|
|
209
|
+
click.echo(f"š” Fetching: {manifest_url}")
|
|
210
|
+
|
|
211
|
+
response = client.get(manifest_url)
|
|
212
|
+
response.raise_for_status()
|
|
213
|
+
|
|
214
|
+
manifest_data = response.json()
|
|
215
|
+
|
|
216
|
+
if verbose and not output_json:
|
|
217
|
+
click.echo("\nš Received manifest:")
|
|
218
|
+
click.echo(json.dumps(manifest_data, indent=2))
|
|
219
|
+
|
|
220
|
+
# Parse into CapabilityManifest
|
|
221
|
+
manifest = CapabilityManifest(**manifest_data)
|
|
222
|
+
|
|
223
|
+
# Calculate trust score (0-10 scale, convert to 0-100)
|
|
224
|
+
trust_score_10 = manifest.calculate_trust_score()
|
|
225
|
+
trust_score_100 = int(trust_score_10 * 10)
|
|
226
|
+
|
|
227
|
+
# Determine risk level
|
|
228
|
+
if trust_score_100 >= 80:
|
|
229
|
+
risk_level = "š¢ LOW"
|
|
230
|
+
risk_emoji = "ā
"
|
|
231
|
+
elif trust_score_100 >= 50:
|
|
232
|
+
risk_level = "š” MEDIUM"
|
|
233
|
+
risk_emoji = "ā ļø"
|
|
234
|
+
else:
|
|
235
|
+
risk_level = "š“ HIGH"
|
|
236
|
+
risk_emoji = "ā"
|
|
237
|
+
|
|
238
|
+
if output_json:
|
|
239
|
+
print(json.dumps({
|
|
240
|
+
"status": "success",
|
|
241
|
+
"agent_id": manifest.agent_id,
|
|
242
|
+
"trust_score": trust_score_100,
|
|
243
|
+
"risk_level": risk_level.strip().split()[-1],
|
|
244
|
+
"trust_level": manifest.trust_level.value,
|
|
245
|
+
"reversibility": manifest.capabilities.reversibility.value,
|
|
246
|
+
"retention": manifest.privacy_contract.retention.value,
|
|
247
|
+
"manifest": manifest_data if verbose else None
|
|
248
|
+
}, indent=2))
|
|
249
|
+
else:
|
|
250
|
+
# Display results
|
|
251
|
+
click.echo(f"\n{risk_emoji} Trust Score: {trust_score_100}/100 ({risk_level})")
|
|
252
|
+
click.echo("\nš Agent Profile:")
|
|
253
|
+
click.echo(f" Agent ID: {manifest.agent_id}")
|
|
254
|
+
click.echo(f" Trust Level: {manifest.trust_level.value}")
|
|
255
|
+
click.echo(f" Reversibility: {manifest.capabilities.reversibility.value}")
|
|
256
|
+
click.echo(f" Data Retention: {manifest.privacy_contract.retention.value}")
|
|
257
|
+
|
|
258
|
+
# Security indicators
|
|
259
|
+
click.echo("\nš Security Indicators:")
|
|
260
|
+
click.echo(f" {'ā
' if manifest.capabilities.idempotency else 'ā'} Idempotent operations")
|
|
261
|
+
click.echo(f" {'ā
' if manifest.capabilities.reversibility != ReversibilityLevel.NONE else 'ā'} Reversibility support")
|
|
262
|
+
click.echo(f" {'ā
' if manifest.privacy_contract.retention != RetentionPolicy.PERMANENT else 'ā'} Limited data retention")
|
|
263
|
+
click.echo(f" {'ā ļø' if manifest.privacy_contract.human_review else 'ā
'} {'Human review enabled' if manifest.privacy_contract.human_review else 'Automated processing'}")
|
|
264
|
+
|
|
265
|
+
# Recommendations
|
|
266
|
+
if trust_score_100 < 50:
|
|
267
|
+
click.echo("\nā ļø Recommendations:")
|
|
268
|
+
click.echo(" ⢠This agent has a low trust score")
|
|
269
|
+
click.echo(" ⢠Use X-User-Override: true header to proceed")
|
|
270
|
+
click.echo(" ⢠Avoid sending sensitive data")
|
|
271
|
+
click.echo(" ⢠Monitor quarantine logs")
|
|
272
|
+
|
|
273
|
+
if verbose:
|
|
274
|
+
click.echo("\nš Performance Guarantees:")
|
|
275
|
+
if manifest.capabilities.rate_limit:
|
|
276
|
+
click.echo(f" Rate Limit: {manifest.capabilities.rate_limit} req/min")
|
|
277
|
+
if manifest.capabilities.sla_latency:
|
|
278
|
+
click.echo(f" SLA Latency: {manifest.capabilities.sla_latency}")
|
|
279
|
+
|
|
280
|
+
except Exception as e:
|
|
281
|
+
# Sanitize error message based on exception type to prevent info leakage
|
|
282
|
+
is_known = isinstance(e, (httpx.RequestError, json.JSONDecodeError, ValueError, PermissionError))
|
|
283
|
+
err_msg = "An error occurred fetching or validating the agent manifest." if is_known else "An internal error occurred during agent scan"
|
|
284
|
+
|
|
285
|
+
if output_json:
|
|
286
|
+
print(json.dumps({
|
|
287
|
+
"status": "fail",
|
|
288
|
+
"error": err_msg,
|
|
289
|
+
"type": "ScanDataError" if is_known else "InternalError"
|
|
290
|
+
}, indent=2))
|
|
291
|
+
else:
|
|
292
|
+
click.echo(f"\nā Scan error: {err_msg}", err=True)
|
|
293
|
+
if verbose and not is_known:
|
|
294
|
+
import traceback
|
|
295
|
+
click.echo(traceback.format_exc(), err=True)
|
|
296
|
+
sys.exit(1)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@cli.command()
|
|
300
|
+
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
|
|
301
|
+
def version(output_json: bool):
|
|
302
|
+
"""Show IATP version information."""
|
|
303
|
+
if output_json:
|
|
304
|
+
print(json.dumps({
|
|
305
|
+
"name": "IATP CLI",
|
|
306
|
+
"version": __version__,
|
|
307
|
+
"description": "Inter-Agent Trust Protocol",
|
|
308
|
+
"url": "https://github.com/microsoft/agent-governance-toolkit"
|
|
309
|
+
}, indent=2))
|
|
310
|
+
else:
|
|
311
|
+
click.echo(f"IATP CLI v{__version__}")
|
|
312
|
+
click.echo("Inter-Agent Trust Protocol")
|
|
313
|
+
click.echo("https://github.com/microsoft/agent-governance-toolkit")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
if __name__ == '__main__':
|
|
317
|
+
cli()
|