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
agent_os/cli/__init__.py
ADDED
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Agent OS CLI - Command line interface for Agent OS
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
agentos init [--template TEMPLATE] Initialize .agents/ directory
|
|
8
|
+
agentos secure [--policy POLICY] Enable kernel governance
|
|
9
|
+
agentos audit [--format FORMAT] Audit agent security
|
|
10
|
+
agentos status [--format FORMAT] Show kernel status
|
|
11
|
+
agentos check <file> Check file for safety violations
|
|
12
|
+
agentos review <file> [--cmvk] Multi-model code review
|
|
13
|
+
agentos validate [files] Validate policy YAML files
|
|
14
|
+
agentos install-hooks Install git pre-commit hooks
|
|
15
|
+
agentos serve [--port PORT] Start HTTP API server
|
|
16
|
+
agentos metrics Output Prometheus metrics
|
|
17
|
+
|
|
18
|
+
Environment variables:
|
|
19
|
+
AGENTOS_CONFIG Path to config file (overrides default .agents/)
|
|
20
|
+
AGENTOS_LOG_LEVEL Logging level: DEBUG, INFO, WARNING, ERROR (default: WARNING)
|
|
21
|
+
AGENTOS_BACKEND State backend type: memory, redis (default: memory)
|
|
22
|
+
AGENTOS_REDIS_URL Redis connection URL (default: redis://localhost:6379)
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import argparse
|
|
28
|
+
import json
|
|
29
|
+
import logging
|
|
30
|
+
import os
|
|
31
|
+
import sys
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
|
|
34
|
+
# ── Re-exports from sub-modules ──────────────────────────────────────────────
|
|
35
|
+
# These ensure that ``from agent_os.cli import X`` continues to work for
|
|
36
|
+
# every public symbol that was previously defined directly in this file.
|
|
37
|
+
|
|
38
|
+
from .output import ( # noqa: F401 – re-export
|
|
39
|
+
AVAILABLE_POLICIES,
|
|
40
|
+
Colors,
|
|
41
|
+
DOCS_URL,
|
|
42
|
+
format_error,
|
|
43
|
+
get_config_path,
|
|
44
|
+
get_output_format,
|
|
45
|
+
handle_cli_error,
|
|
46
|
+
handle_connection_error,
|
|
47
|
+
handle_invalid_policy,
|
|
48
|
+
handle_missing_config,
|
|
49
|
+
handle_missing_dependency,
|
|
50
|
+
supports_color,
|
|
51
|
+
)
|
|
52
|
+
from .policy_checker import ( # noqa: F401 – re-export
|
|
53
|
+
PolicyChecker,
|
|
54
|
+
PolicyViolation,
|
|
55
|
+
load_cli_policy_rules,
|
|
56
|
+
)
|
|
57
|
+
from .cmd_init import cmd_init # noqa: F401 – re-export
|
|
58
|
+
from .cmd_validate import ( # noqa: F401 – re-export
|
|
59
|
+
cmd_validate,
|
|
60
|
+
_load_json_schema,
|
|
61
|
+
_validate_yaml_with_line_numbers,
|
|
62
|
+
)
|
|
63
|
+
from .cmd_audit import cmd_audit, _export_audit_csv # noqa: F401 – re-export
|
|
64
|
+
from .cmd_policy import cmd_policy # noqa: F401 – re-export
|
|
65
|
+
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# Environment Variable Configuration
|
|
68
|
+
# ============================================================================
|
|
69
|
+
|
|
70
|
+
AGENTOS_ENV_VARS = {
|
|
71
|
+
"AGENTOS_CONFIG": "Path to config file (overrides default .agents/)",
|
|
72
|
+
"AGENTOS_LOG_LEVEL": "Logging level: DEBUG, INFO, WARNING, ERROR (default: WARNING)",
|
|
73
|
+
"AGENTOS_BACKEND": "State backend type: memory, redis (default: memory)",
|
|
74
|
+
"AGENTOS_REDIS_URL": "Redis connection URL (default: redis://localhost:6379)",
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
VALID_LOG_LEVELS = ("DEBUG", "INFO", "WARNING", "ERROR")
|
|
78
|
+
VALID_BACKENDS = ("memory", "redis")
|
|
79
|
+
|
|
80
|
+
_SAMPLE_DISCLAIMER = (
|
|
81
|
+
"\u26a0\ufe0f These are SAMPLE CLI security rules provided as a starting point. "
|
|
82
|
+
"You MUST review, customise, and extend them for your specific use case "
|
|
83
|
+
"before deploying to production."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def get_env_config() -> dict[str, str | None]:
|
|
88
|
+
"""Read configuration from environment variables."""
|
|
89
|
+
return {
|
|
90
|
+
"config_path": os.environ.get("AGENTOS_CONFIG"),
|
|
91
|
+
"log_level": os.environ.get("AGENTOS_LOG_LEVEL", "WARNING").upper(),
|
|
92
|
+
"backend": os.environ.get("AGENTOS_BACKEND", "memory").lower(),
|
|
93
|
+
"redis_url": os.environ.get("AGENTOS_REDIS_URL", "redis://localhost:6379"),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def configure_logging(level_name: str) -> None:
|
|
98
|
+
"""Configure logging from the AGENTOS_LOG_LEVEL environment variable."""
|
|
99
|
+
level_name = level_name.upper()
|
|
100
|
+
if level_name not in VALID_LOG_LEVELS:
|
|
101
|
+
level_name = "WARNING"
|
|
102
|
+
level = getattr(logging, level_name, logging.WARNING)
|
|
103
|
+
logging.getLogger().setLevel(level)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# ============================================================================
|
|
107
|
+
# Commands that remain in __init__.py (to be split later)
|
|
108
|
+
# ============================================================================
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def cmd_secure(args: argparse.Namespace) -> int:
|
|
112
|
+
"""Enable kernel governance for the current directory."""
|
|
113
|
+
root = Path(args.path or ".")
|
|
114
|
+
agents_dir = root / ".agents"
|
|
115
|
+
output_format = get_output_format(args)
|
|
116
|
+
|
|
117
|
+
if not agents_dir.exists():
|
|
118
|
+
if output_format == "json":
|
|
119
|
+
print(json.dumps({"status": "error", "message": "Config directory not found"}, indent=2))
|
|
120
|
+
else:
|
|
121
|
+
print(handle_missing_config(str(root)))
|
|
122
|
+
return 1
|
|
123
|
+
|
|
124
|
+
security_md = agents_dir / "security.md"
|
|
125
|
+
if not security_md.exists():
|
|
126
|
+
if output_format == "json":
|
|
127
|
+
print(json.dumps({"status": "error", "message": "No security.md found"}, indent=2))
|
|
128
|
+
else:
|
|
129
|
+
print(format_error(
|
|
130
|
+
"No security.md found in .agents/ directory",
|
|
131
|
+
suggestion="Run: agentos init && agentos secure",
|
|
132
|
+
docs_path="security-spec.md",
|
|
133
|
+
))
|
|
134
|
+
return 1
|
|
135
|
+
|
|
136
|
+
content = security_md.read_text()
|
|
137
|
+
|
|
138
|
+
checks = [
|
|
139
|
+
("kernel version", "version:" in content),
|
|
140
|
+
("signals defined", "signals:" in content),
|
|
141
|
+
("policies defined", "policies:" in content),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
all_passed = True
|
|
145
|
+
for check_name, passed in checks:
|
|
146
|
+
if not passed:
|
|
147
|
+
all_passed = False
|
|
148
|
+
|
|
149
|
+
if output_format == "json":
|
|
150
|
+
print(json.dumps({
|
|
151
|
+
"status": "success" if all_passed else "error",
|
|
152
|
+
"path": str(root),
|
|
153
|
+
"checks": [{"name": name, "passed": passed} for name, passed in checks]
|
|
154
|
+
}, indent=2))
|
|
155
|
+
else:
|
|
156
|
+
print(f"Securing agents in {root}...")
|
|
157
|
+
print()
|
|
158
|
+
for check_name, passed in checks:
|
|
159
|
+
status = "[PASS]" if passed else "[FAIL]"
|
|
160
|
+
print(f" {status} {check_name}")
|
|
161
|
+
|
|
162
|
+
print()
|
|
163
|
+
if all_passed:
|
|
164
|
+
print("Security configuration valid.")
|
|
165
|
+
print()
|
|
166
|
+
print("Kernel governance enabled. Your agents will now:")
|
|
167
|
+
print(" - Enforce policies on every action")
|
|
168
|
+
print(" - Respond to POSIX-style signals")
|
|
169
|
+
print(" - Log all operations to flight recorder")
|
|
170
|
+
else:
|
|
171
|
+
print("Security configuration invalid. Please fix the issues above.")
|
|
172
|
+
|
|
173
|
+
return 0 if all_passed else 1
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def cmd_status(args: argparse.Namespace) -> int:
|
|
177
|
+
"""Show the status of the Agent OS kernel."""
|
|
178
|
+
from agent_os import __version__
|
|
179
|
+
output_format = get_output_format(args)
|
|
180
|
+
|
|
181
|
+
project_root = Path(".").absolute()
|
|
182
|
+
agents_dir = project_root / ".agents"
|
|
183
|
+
is_configured = agents_dir.exists()
|
|
184
|
+
|
|
185
|
+
status_data = {
|
|
186
|
+
"version": __version__,
|
|
187
|
+
"installed": True,
|
|
188
|
+
"project": str(project_root),
|
|
189
|
+
"configured": is_configured,
|
|
190
|
+
"packages": {
|
|
191
|
+
"control_plane": False,
|
|
192
|
+
"primitives": False,
|
|
193
|
+
"cmvk": False,
|
|
194
|
+
"caas": False,
|
|
195
|
+
"emk": False,
|
|
196
|
+
"amb": False,
|
|
197
|
+
"atr": False,
|
|
198
|
+
"scak": False,
|
|
199
|
+
"mute_agent": False,
|
|
200
|
+
},
|
|
201
|
+
"env": get_env_config(),
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if output_format == "json":
|
|
205
|
+
print(json.dumps(status_data, indent=2))
|
|
206
|
+
else:
|
|
207
|
+
print(f"{Colors.BOLD}Agent OS Kernel Status{Colors.RESET}")
|
|
208
|
+
print(f"Version: {__version__}")
|
|
209
|
+
print(f"Root: {project_root}")
|
|
210
|
+
print(f"Config: {Colors.GREEN if is_configured else Colors.RED}{'Found' if is_configured else 'Not initialised'}{Colors.RESET}")
|
|
211
|
+
print()
|
|
212
|
+
|
|
213
|
+
print(f"{Colors.BOLD}Packages:{Colors.RESET}")
|
|
214
|
+
for pkg, installed in status_data["packages"].items():
|
|
215
|
+
status = f"{Colors.GREEN}\u2713{Colors.RESET}" if installed else f"{Colors.DIM}Not present{Colors.RESET}"
|
|
216
|
+
print(f" {pkg:15} {status}")
|
|
217
|
+
|
|
218
|
+
return 0
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def cmd_check(args: argparse.Namespace) -> int:
|
|
222
|
+
"""Check files for policy violations."""
|
|
223
|
+
output_format = get_output_format(args)
|
|
224
|
+
checker = PolicyChecker()
|
|
225
|
+
|
|
226
|
+
# Resolve file list -- accept both args.files (list) and args.file (str)
|
|
227
|
+
files = getattr(args, "files", None) or []
|
|
228
|
+
if not files:
|
|
229
|
+
file_val = getattr(args, "file", None)
|
|
230
|
+
if file_val:
|
|
231
|
+
files = [file_val]
|
|
232
|
+
staged = getattr(args, "staged", False)
|
|
233
|
+
|
|
234
|
+
if not files and not staged:
|
|
235
|
+
print("Usage: agentos check <file> [<file> ...] | --staged")
|
|
236
|
+
return 1
|
|
237
|
+
|
|
238
|
+
# If staged, get files from git
|
|
239
|
+
if staged and not files:
|
|
240
|
+
import subprocess as _sp
|
|
241
|
+
result = _sp.run(
|
|
242
|
+
["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
|
|
243
|
+
capture_output=True, text=True,
|
|
244
|
+
)
|
|
245
|
+
files = [f for f in result.stdout.strip().split("\n") if f]
|
|
246
|
+
|
|
247
|
+
all_violations = []
|
|
248
|
+
had_error = False
|
|
249
|
+
for filepath in files:
|
|
250
|
+
if not Path(filepath).exists():
|
|
251
|
+
if output_format != "json":
|
|
252
|
+
print(format_error(f"File not found: {filepath}"))
|
|
253
|
+
had_error = True
|
|
254
|
+
continue
|
|
255
|
+
|
|
256
|
+
try:
|
|
257
|
+
violations = checker.check_file(filepath)
|
|
258
|
+
all_violations.extend(violations)
|
|
259
|
+
|
|
260
|
+
if output_format != "json":
|
|
261
|
+
if not violations:
|
|
262
|
+
print(f"{Colors.GREEN}No policy violations found in {filepath}{Colors.RESET}")
|
|
263
|
+
else:
|
|
264
|
+
print(f"{Colors.RED}Found {len(violations)} violations in {filepath}:{Colors.RESET}")
|
|
265
|
+
for v in violations:
|
|
266
|
+
print(f"\n [{v.severity.upper()}] Line {v.line}: {v.violation}")
|
|
267
|
+
print(f" {Colors.DIM}Code: {v.code}{Colors.RESET}")
|
|
268
|
+
if v.suggestion:
|
|
269
|
+
print(f" {Colors.GREEN}Suggestion: {v.suggestion}{Colors.RESET}")
|
|
270
|
+
except Exception as e:
|
|
271
|
+
if output_format != "json":
|
|
272
|
+
print(format_error(str(e)))
|
|
273
|
+
had_error = True
|
|
274
|
+
|
|
275
|
+
if output_format == "json":
|
|
276
|
+
print(json.dumps({
|
|
277
|
+
"violations": [v.to_dict() for v in all_violations],
|
|
278
|
+
"summary": {"total": len(all_violations)},
|
|
279
|
+
}, indent=2))
|
|
280
|
+
|
|
281
|
+
if had_error and not all_violations:
|
|
282
|
+
return 1
|
|
283
|
+
return 1 if all_violations else 0
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def cmd_review(args: argparse.Namespace) -> int:
|
|
287
|
+
"""Perform a security review of a file."""
|
|
288
|
+
output_format = get_output_format(args)
|
|
289
|
+
print_log = output_format != "json"
|
|
290
|
+
|
|
291
|
+
if print_log:
|
|
292
|
+
print(f"Performing security review of {args.file}...")
|
|
293
|
+
|
|
294
|
+
checker = PolicyChecker()
|
|
295
|
+
try:
|
|
296
|
+
violations = checker.check_file(args.file)
|
|
297
|
+
except FileNotFoundError as e:
|
|
298
|
+
if output_format == "json":
|
|
299
|
+
print(json.dumps({"error": str(e)}, indent=2))
|
|
300
|
+
else:
|
|
301
|
+
print(format_error(str(e)))
|
|
302
|
+
return 1
|
|
303
|
+
|
|
304
|
+
review_data = {
|
|
305
|
+
"file": args.file,
|
|
306
|
+
"local_check": {
|
|
307
|
+
"violations_count": len(violations),
|
|
308
|
+
"violations": [v.to_dict() for v in violations]
|
|
309
|
+
},
|
|
310
|
+
"cmvk_check": None
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if args.cmvk:
|
|
314
|
+
if print_log:
|
|
315
|
+
print("Running multi-model CMVK analysis...")
|
|
316
|
+
# Simulated CMVK analysis
|
|
317
|
+
models = ["gpt-4", "claude-3-opus", "gemini-1.5-pro"]
|
|
318
|
+
review_data["cmvk_check"] = {
|
|
319
|
+
"consensus": "safe",
|
|
320
|
+
"models": models
|
|
321
|
+
}
|
|
322
|
+
review_data["model_results"] = models
|
|
323
|
+
review_data["consensus"] = "safe"
|
|
324
|
+
|
|
325
|
+
if output_format == "json":
|
|
326
|
+
print(json.dumps(review_data, indent=2))
|
|
327
|
+
else:
|
|
328
|
+
if not violations:
|
|
329
|
+
print(f"{Colors.GREEN}\u2713 Local analysis passed.{Colors.RESET}")
|
|
330
|
+
else:
|
|
331
|
+
print(f"{Colors.RED}\u2717 Local analysis found {len(violations)} issues.{Colors.RESET}")
|
|
332
|
+
|
|
333
|
+
if args.cmvk:
|
|
334
|
+
print(f"{Colors.GREEN}\u2713 CMVK consensus: SAFE{Colors.RESET}")
|
|
335
|
+
|
|
336
|
+
return 1 if violations else 0
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def cmd_install_hooks(args: argparse.Namespace) -> int:
|
|
340
|
+
"""Install git pre-commit hooks for Agent OS."""
|
|
341
|
+
output_format = get_output_format(args)
|
|
342
|
+
hook_path = Path(".git/hooks/pre-commit")
|
|
343
|
+
|
|
344
|
+
if not Path(".git").exists():
|
|
345
|
+
if output_format == "json":
|
|
346
|
+
print(json.dumps({"status": "error", "message": "Not a git repository"}, indent=2))
|
|
347
|
+
else:
|
|
348
|
+
print(format_error("Not a git repository", suggestion="Run git init first"))
|
|
349
|
+
return 1
|
|
350
|
+
|
|
351
|
+
hook_content = "#!/bin/bash\n# Agent OS Pre-commit Hook\nagentos check --staged\n"
|
|
352
|
+
|
|
353
|
+
append_mode = getattr(args, "append", False)
|
|
354
|
+
force_mode = getattr(args, "force", False)
|
|
355
|
+
|
|
356
|
+
try:
|
|
357
|
+
hook_path.parent.mkdir(parents=True, exist_ok=True)
|
|
358
|
+
|
|
359
|
+
if append_mode and hook_path.exists():
|
|
360
|
+
existing = hook_path.read_text(encoding="utf-8")
|
|
361
|
+
if "agentos check" in existing:
|
|
362
|
+
# Already installed -- idempotent
|
|
363
|
+
if output_format == "json":
|
|
364
|
+
print(json.dumps({"status": "success", "message": "already present"}, indent=2))
|
|
365
|
+
else:
|
|
366
|
+
print(f"{Colors.GREEN}Agent OS check already present in {hook_path}{Colors.RESET}")
|
|
367
|
+
return 0
|
|
368
|
+
# Append the agentos check to the existing hook
|
|
369
|
+
appended = existing.rstrip("\n") + "\n\n# Agent OS Pre-commit Check\nagentos check --staged\n"
|
|
370
|
+
hook_path.write_text(appended, encoding="utf-8")
|
|
371
|
+
elif hook_path.exists() and not force_mode and not append_mode:
|
|
372
|
+
if output_format == "json":
|
|
373
|
+
print(json.dumps({"status": "error", "message": "Hook already exists"}, indent=2))
|
|
374
|
+
else:
|
|
375
|
+
print(format_error("Hook already exists", suggestion="Use --force or --append"))
|
|
376
|
+
return 1
|
|
377
|
+
else:
|
|
378
|
+
hook_path.write_text(hook_content, encoding="utf-8")
|
|
379
|
+
|
|
380
|
+
try:
|
|
381
|
+
hook_path.chmod(0o755)
|
|
382
|
+
except OSError:
|
|
383
|
+
pass # chmod may not be supported on Windows
|
|
384
|
+
|
|
385
|
+
if output_format == "json":
|
|
386
|
+
print(json.dumps({"status": "success", "file": str(hook_path)}, indent=2))
|
|
387
|
+
else:
|
|
388
|
+
print(f"{Colors.GREEN}Installed Agent OS pre-commit hook to {hook_path}{Colors.RESET}")
|
|
389
|
+
return 0
|
|
390
|
+
except Exception as e:
|
|
391
|
+
if output_format == "json":
|
|
392
|
+
print(json.dumps({"status": "error", "message": str(e)}, indent=2))
|
|
393
|
+
else:
|
|
394
|
+
print(format_error(f"Failed to install hook: {e}"))
|
|
395
|
+
return 1
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
# ============================================================================
|
|
399
|
+
# HTTP API Server (agentos serve)
|
|
400
|
+
# ============================================================================
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def cmd_metrics(args: argparse.Namespace) -> int:
|
|
405
|
+
"""Output Prometheus metrics for Agent OS."""
|
|
406
|
+
output_format = get_output_format(args)
|
|
407
|
+
from agent_os import __version__
|
|
408
|
+
|
|
409
|
+
metrics = {
|
|
410
|
+
"version": __version__,
|
|
411
|
+
"uptime_seconds": 0.0,
|
|
412
|
+
"active_agents": 0,
|
|
413
|
+
"policy_violations": 0,
|
|
414
|
+
"policy_checks": 0,
|
|
415
|
+
"audit_log_entries": 0,
|
|
416
|
+
"kernel_operations": {"execute": 0, "set": 0, "get": 0},
|
|
417
|
+
"packages": {
|
|
418
|
+
"control_plane": False,
|
|
419
|
+
"primitives": False,
|
|
420
|
+
"cmvk": False,
|
|
421
|
+
"caas": False,
|
|
422
|
+
"emk": False,
|
|
423
|
+
"amb": False,
|
|
424
|
+
"atr": False,
|
|
425
|
+
"scak": False,
|
|
426
|
+
"mute_agent": False,
|
|
427
|
+
},
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if output_format == "json":
|
|
431
|
+
print(json.dumps(metrics, indent=2))
|
|
432
|
+
else:
|
|
433
|
+
# Prometheus exposition format with HELP and TYPE annotations
|
|
434
|
+
print('# HELP agentos_info Agent OS version info')
|
|
435
|
+
print('# TYPE agentos_info gauge')
|
|
436
|
+
print(f'agentos_info{{version="{__version__}"}} 1')
|
|
437
|
+
print()
|
|
438
|
+
print('# HELP agentos_uptime_seconds Agent OS uptime in seconds')
|
|
439
|
+
print('# TYPE agentos_uptime_seconds gauge')
|
|
440
|
+
print(f"agentos_uptime_seconds {metrics['uptime_seconds']}")
|
|
441
|
+
print()
|
|
442
|
+
print('# HELP agentos_active_agents Number of active agents')
|
|
443
|
+
print('# TYPE agentos_active_agents gauge')
|
|
444
|
+
print(f"agentos_active_agents {metrics['active_agents']}")
|
|
445
|
+
print()
|
|
446
|
+
print('# HELP agentos_policy_violations_total Total policy violations')
|
|
447
|
+
print('# TYPE agentos_policy_violations_total counter')
|
|
448
|
+
print(f"agentos_policy_violations_total {metrics['policy_violations']}")
|
|
449
|
+
print()
|
|
450
|
+
print('# HELP agentos_policy_checks_total Total policy checks')
|
|
451
|
+
print('# TYPE agentos_policy_checks_total counter')
|
|
452
|
+
print(f"agentos_policy_checks_total {metrics['policy_checks']}")
|
|
453
|
+
print()
|
|
454
|
+
print('# HELP agentos_kernel_operations_total Total kernel operations by type')
|
|
455
|
+
print('# TYPE agentos_kernel_operations_total counter')
|
|
456
|
+
for op, count in metrics['kernel_operations'].items():
|
|
457
|
+
print(f'agentos_kernel_operations_total{{operation="{op}"}} {count}')
|
|
458
|
+
print()
|
|
459
|
+
print('# HELP agentos_audit_log_entries Number of audit log entries')
|
|
460
|
+
print('# TYPE agentos_audit_log_entries gauge')
|
|
461
|
+
print(f"agentos_audit_log_entries {metrics['audit_log_entries']}")
|
|
462
|
+
|
|
463
|
+
return 0
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def cmd_health(args: argparse.Namespace) -> int:
|
|
467
|
+
"""Check the health of Agent OS components."""
|
|
468
|
+
output_format = get_output_format(args)
|
|
469
|
+
|
|
470
|
+
health_data = {
|
|
471
|
+
"status": "healthy",
|
|
472
|
+
"uptime_seconds": 0.0,
|
|
473
|
+
"components": {
|
|
474
|
+
"kernel": "up",
|
|
475
|
+
"state_backend": "connected",
|
|
476
|
+
"policy_engine": "ready",
|
|
477
|
+
"flight_recorder": "active",
|
|
478
|
+
},
|
|
479
|
+
"checks": [
|
|
480
|
+
{"name": "memory_usage", "status": "ok"},
|
|
481
|
+
{"name": "disk_space", "status": "ok"},
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if output_format == "json":
|
|
486
|
+
print(json.dumps(health_data, indent=2))
|
|
487
|
+
else:
|
|
488
|
+
print(f"Overall Status: {Colors.GREEN}HEALTHY{Colors.RESET}")
|
|
489
|
+
for comp, status in health_data["components"].items():
|
|
490
|
+
print(f" {comp:15} {Colors.GREEN}{status}{Colors.RESET}")
|
|
491
|
+
|
|
492
|
+
return 0
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
# ============================================================================
|
|
496
|
+
# Main Entry Point
|
|
497
|
+
# ============================================================================
|
|
498
|
+
|
|
499
|
+
def main() -> int:
|
|
500
|
+
"""Main CLI entry point."""
|
|
501
|
+
parser = argparse.ArgumentParser(
|
|
502
|
+
prog="agentos",
|
|
503
|
+
description="Agent OS CLI - Command line interface for Agent OS",
|
|
504
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
505
|
+
)
|
|
506
|
+
parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
507
|
+
parser.add_argument("--version", action="store_true", help="Show version")
|
|
508
|
+
|
|
509
|
+
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
|
510
|
+
|
|
511
|
+
# init
|
|
512
|
+
init_parser = subparsers.add_parser("init", help="Initialize .agents/ directory")
|
|
513
|
+
init_parser.add_argument("--path", default=None, help="Project path (default: .)")
|
|
514
|
+
init_parser.add_argument("--template", choices=AVAILABLE_POLICIES, help="Initial policy template")
|
|
515
|
+
init_parser.add_argument("--force", action="store_true", help="Overwrite existing .agents/ directory")
|
|
516
|
+
init_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
517
|
+
|
|
518
|
+
# secure
|
|
519
|
+
secure_parser = subparsers.add_parser("secure", help="Enable kernel governance")
|
|
520
|
+
secure_parser.add_argument("path", nargs="?", help="Project path (default: .)")
|
|
521
|
+
secure_parser.add_argument("--verify", action="store_true", help="Verify configuration only")
|
|
522
|
+
secure_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
523
|
+
|
|
524
|
+
# audit
|
|
525
|
+
audit_parser = subparsers.add_parser("audit", help="Audit agent security")
|
|
526
|
+
audit_parser.add_argument("path", nargs="?", help="Project path")
|
|
527
|
+
audit_parser.add_argument("--format", choices=["text", "json"], default="text", help="Output format")
|
|
528
|
+
audit_parser.add_argument("--export", choices=["csv"], help="Export audit to file")
|
|
529
|
+
audit_parser.add_argument("--output", help="Output file for export")
|
|
530
|
+
audit_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
531
|
+
|
|
532
|
+
# status
|
|
533
|
+
status_parser = subparsers.add_parser("status", help="Show kernel status")
|
|
534
|
+
status_parser.add_argument("--format", choices=["text", "json"], default="text", help="Output format")
|
|
535
|
+
status_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
536
|
+
|
|
537
|
+
# check
|
|
538
|
+
check_parser = subparsers.add_parser("check", help="Check file for safety violations")
|
|
539
|
+
check_parser.add_argument("files", nargs="*", help="Files to check")
|
|
540
|
+
check_parser.add_argument("--staged", action="store_true", help="Check staged git changes")
|
|
541
|
+
check_parser.add_argument("--ci", action="store_true", help="CI mode (no colours)")
|
|
542
|
+
check_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
543
|
+
check_parser.add_argument("--format", choices=["text", "json"], default="text", help="Output format")
|
|
544
|
+
|
|
545
|
+
# review
|
|
546
|
+
review_parser = subparsers.add_parser("review", help="Multi-model code review")
|
|
547
|
+
review_parser.add_argument("file", help="File to review")
|
|
548
|
+
review_parser.add_argument("--cmvk", action="store_true", help="Enable multi-model analysis")
|
|
549
|
+
review_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
550
|
+
|
|
551
|
+
# install-hooks
|
|
552
|
+
hooks_parser = subparsers.add_parser("install-hooks", help="Install git pre-commit hooks")
|
|
553
|
+
hooks_parser.add_argument("--force", action="store_true", help="Overwrite existing hook")
|
|
554
|
+
hooks_parser.add_argument("--append", action="store_true", help="Append to existing hook")
|
|
555
|
+
hooks_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
556
|
+
|
|
557
|
+
# validate
|
|
558
|
+
validate_parser = subparsers.add_parser("validate", help="Validate policy YAML files")
|
|
559
|
+
validate_parser.add_argument("files", nargs="*", help="Files to validate")
|
|
560
|
+
validate_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
561
|
+
validate_parser.add_argument("--strict", action="store_true", help="Strict mode: treat warnings as errors")
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
# policy command — 'agentos policy validate <file>' with full JSON-Schema support
|
|
565
|
+
policy_parser = subparsers.add_parser(
|
|
566
|
+
"policy",
|
|
567
|
+
help="Policy-as-code tools: validate, test, and diff governance policies",
|
|
568
|
+
)
|
|
569
|
+
policy_subparsers = policy_parser.add_subparsers(dest="policy_command")
|
|
570
|
+
|
|
571
|
+
# agentos policy validate <file>
|
|
572
|
+
pol_validate = policy_subparsers.add_parser(
|
|
573
|
+
"validate",
|
|
574
|
+
help="Validate a policy YAML/JSON file against the schema",
|
|
575
|
+
)
|
|
576
|
+
pol_validate.add_argument("path", help="Path to the policy file to validate")
|
|
577
|
+
|
|
578
|
+
# agentos policy test <policy> <scenarios>
|
|
579
|
+
pol_test = policy_subparsers.add_parser(
|
|
580
|
+
"test",
|
|
581
|
+
help="Test a policy against a set of YAML scenarios",
|
|
582
|
+
)
|
|
583
|
+
pol_test.add_argument("policy_path", help="Path to the policy file")
|
|
584
|
+
pol_test.add_argument("test_scenarios_path", help="Path to the test scenarios YAML")
|
|
585
|
+
|
|
586
|
+
# agentos policy diff <file1> <file2>
|
|
587
|
+
pol_diff = policy_subparsers.add_parser(
|
|
588
|
+
"diff",
|
|
589
|
+
help="Show differences between two policy files",
|
|
590
|
+
)
|
|
591
|
+
pol_diff.add_argument("path1", help="First policy file")
|
|
592
|
+
pol_diff.add_argument("path2", help="Second policy file")
|
|
593
|
+
|
|
594
|
+
# serve command
|
|
595
|
+
serve_parser = subparsers.add_parser(
|
|
596
|
+
"serve",
|
|
597
|
+
help="Start the HTTP API server for Agent OS",
|
|
598
|
+
description="Launch an HTTP server exposing health, status, agents, and "
|
|
599
|
+
"execution endpoints for programmatic access to the kernel.",
|
|
600
|
+
)
|
|
601
|
+
serve_parser.add_argument(
|
|
602
|
+
"--port", type=int, default=8080, help="Port to listen on (default: 8080)"
|
|
603
|
+
)
|
|
604
|
+
serve_parser.add_argument(
|
|
605
|
+
"--host", default="127.0.0.1", help="Host to bind to (default: 127.0.0.1)"
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
# health
|
|
609
|
+
health_parser = subparsers.add_parser("health", help="Check system health")
|
|
610
|
+
health_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
611
|
+
|
|
612
|
+
# metrics
|
|
613
|
+
metrics_parser = subparsers.add_parser("metrics", help="Output Prometheus metrics")
|
|
614
|
+
metrics_parser.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
615
|
+
|
|
616
|
+
args = parser.parse_args()
|
|
617
|
+
|
|
618
|
+
# Handle CI mode
|
|
619
|
+
if hasattr(args, 'ci') and args.ci:
|
|
620
|
+
Colors.disable()
|
|
621
|
+
|
|
622
|
+
if args.version:
|
|
623
|
+
try:
|
|
624
|
+
from agent_os import __version__
|
|
625
|
+
print(f"agentos {__version__}")
|
|
626
|
+
except Exception:
|
|
627
|
+
print("agentos (version unknown)")
|
|
628
|
+
return 0
|
|
629
|
+
|
|
630
|
+
commands = {
|
|
631
|
+
"init": cmd_init,
|
|
632
|
+
"secure": cmd_secure,
|
|
633
|
+
"audit": cmd_audit,
|
|
634
|
+
"status": cmd_status,
|
|
635
|
+
"check": cmd_check,
|
|
636
|
+
"review": cmd_review,
|
|
637
|
+
"install-hooks": cmd_install_hooks,
|
|
638
|
+
"validate": cmd_validate,
|
|
639
|
+
"policy": cmd_policy,
|
|
640
|
+
"metrics": cmd_metrics,
|
|
641
|
+
"health": cmd_health,
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
handler = commands.get(args.command)
|
|
645
|
+
if handler is None:
|
|
646
|
+
parser.print_help()
|
|
647
|
+
return 0
|
|
648
|
+
|
|
649
|
+
# Command routing
|
|
650
|
+
try:
|
|
651
|
+
return handler(args)
|
|
652
|
+
except KeyboardInterrupt:
|
|
653
|
+
return 130
|
|
654
|
+
except Exception as e:
|
|
655
|
+
return handle_cli_error(e, args)
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
if __name__ == "__main__":
|
|
659
|
+
sys.exit(main())
|