nat-engine 1__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.
- mannf/__init__.py +33 -0
- mannf/__main__.py +10 -0
- mannf/_version.py +8 -0
- mannf/agents/__init__.py +7 -0
- mannf/agents/analyzer_agent.py +9 -0
- mannf/agents/base.py +9 -0
- mannf/agents/bdi_agent.py +9 -0
- mannf/agents/belief_state.py +9 -0
- mannf/agents/coordinator_agent.py +9 -0
- mannf/agents/executor_agent.py +9 -0
- mannf/agents/monitor_agent.py +9 -0
- mannf/agents/oracle_agent.py +9 -0
- mannf/agents/planner_agent.py +9 -0
- mannf/agents/test_agent.py +9 -0
- mannf/anomaly/__init__.py +7 -0
- mannf/anomaly/enhanced_detector.py +9 -0
- mannf/cli.py +9 -0
- mannf/core/__init__.py +26 -0
- mannf/core/agents/__init__.py +52 -0
- mannf/core/agents/accessibility_scanner_agent.py +245 -0
- mannf/core/agents/analyzer_agent.py +224 -0
- mannf/core/agents/autonomous_loop_agent.py +1086 -0
- mannf/core/agents/autonomous_loop_models.py +62 -0
- mannf/core/agents/autonomous_run_differ.py +427 -0
- mannf/core/agents/base.py +128 -0
- mannf/core/agents/bdi_agent.py +330 -0
- mannf/core/agents/belief_state.py +202 -0
- mannf/core/agents/browser_coordinator_agent.py +224 -0
- mannf/core/agents/browser_executor_agent.py +410 -0
- mannf/core/agents/coordinator_agent.py +262 -0
- mannf/core/agents/executor_agent.py +222 -0
- mannf/core/agents/monitor_agent.py +188 -0
- mannf/core/agents/oracle_agent.py +150 -0
- mannf/core/agents/performance_testing_agent.py +279 -0
- mannf/core/agents/planner_agent.py +128 -0
- mannf/core/agents/test_agent.py +249 -0
- mannf/core/agents/visual_regression_agent.py +311 -0
- mannf/core/agents/web_crawler_agent.py +510 -0
- mannf/core/agents/worker_pool.py +366 -0
- mannf/core/anomaly/__init__.py +14 -0
- mannf/core/anomaly/enhanced_detector.py +541 -0
- mannf/core/browser/__init__.py +63 -0
- mannf/core/browser/accessibility_scanner.py +424 -0
- mannf/core/browser/discovery_model.py +178 -0
- mannf/core/browser/dom_snapshot.py +349 -0
- mannf/core/browser/ingestor_bridge.py +371 -0
- mannf/core/browser/performance_metrics.py +217 -0
- mannf/core/browser/reflection_analyzer.py +442 -0
- mannf/core/browser/scenario_generator.py +1100 -0
- mannf/core/browser/security_scenario_generator.py +695 -0
- mannf/core/browser/visual_comparer.py +159 -0
- mannf/core/diagnostics/__init__.py +28 -0
- mannf/core/diagnostics/failure_clusterer.py +211 -0
- mannf/core/diagnostics/flake_detector.py +233 -0
- mannf/core/diagnostics/root_cause_analyzer.py +273 -0
- mannf/core/distributed/__init__.py +16 -0
- mannf/core/distributed/endpoint.py +139 -0
- mannf/core/distributed/system_under_test.py +207 -0
- mannf/core/functional_orchestrator.py +428 -0
- mannf/core/messaging/__init__.py +11 -0
- mannf/core/messaging/bus.py +113 -0
- mannf/core/messaging/messages.py +89 -0
- mannf/core/nat_orchestrator.py +342 -0
- mannf/core/neural/__init__.py +183 -0
- mannf/core/orchestrator.py +272 -0
- mannf/core/prioritization/__init__.py +17 -0
- mannf/core/prioritization/adaptive_controller.py +509 -0
- mannf/core/prioritization/belief_prioritizer.py +231 -0
- mannf/core/prioritization/risk_scorer.py +430 -0
- mannf/core/reporting/__init__.py +12 -0
- mannf/core/reporting/unified_report.py +664 -0
- mannf/core/testing/__init__.py +17 -0
- mannf/core/testing/adaptive_controller.py +149 -0
- mannf/core/testing/models.py +179 -0
- mannf/core/validation/__init__.py +10 -0
- mannf/core/validation/self_validation_runner.py +180 -0
- mannf/dashboard/__init__.py +7 -0
- mannf/dashboard/app.py +9 -0
- mannf/dashboard/models.py +9 -0
- mannf/dashboard/static/index.html +2538 -0
- mannf/dashboard/telemetry.py +9 -0
- mannf/distributed/__init__.py +7 -0
- mannf/distributed/endpoint.py +9 -0
- mannf/distributed/system_under_test.py +9 -0
- mannf/healing/__init__.py +7 -0
- mannf/healing/graphql_schema_diff.py +9 -0
- mannf/healing/healer.py +9 -0
- mannf/healing/models.py +9 -0
- mannf/healing/schema_diff.py +9 -0
- mannf/integrations/__init__.py +7 -0
- mannf/integrations/auth.py +9 -0
- mannf/integrations/graphql_parser.py +9 -0
- mannf/integrations/graphql_sut.py +9 -0
- mannf/integrations/http_sut.py +9 -0
- mannf/integrations/openapi_parser.py +9 -0
- mannf/integrations/postman_parser.py +9 -0
- mannf/llm/__init__.py +7 -0
- mannf/llm/anthropic_provider.py +9 -0
- mannf/llm/base.py +9 -0
- mannf/llm/config.py +9 -0
- mannf/llm/factory.py +9 -0
- mannf/llm/openai_provider.py +9 -0
- mannf/llm/prompts.py +9 -0
- mannf/messaging/__init__.py +7 -0
- mannf/messaging/bus.py +9 -0
- mannf/messaging/messages.py +9 -0
- mannf/nat_orchestrator.py +9 -0
- mannf/neural/__init__.py +7 -0
- mannf/orchestrator.py +9 -0
- mannf/prioritization/__init__.py +7 -0
- mannf/prioritization/adaptive_controller.py +9 -0
- mannf/prioritization/belief_prioritizer.py +9 -0
- mannf/prioritization/risk_scorer.py +9 -0
- mannf/product/__init__.py +29 -0
- mannf/product/admin/__init__.py +3 -0
- mannf/product/admin/routes.py +514 -0
- mannf/product/auth/__init__.py +5 -0
- mannf/product/auth/saml.py +212 -0
- mannf/product/billing/__init__.py +5 -0
- mannf/product/billing/audit.py +160 -0
- mannf/product/billing/feature_gates.py +180 -0
- mannf/product/billing/metering.py +179 -0
- mannf/product/billing/notifications.py +181 -0
- mannf/product/billing/plans.py +133 -0
- mannf/product/billing/rate_limits.py +35 -0
- mannf/product/billing/stripe_billing.py +906 -0
- mannf/product/billing/tenant_auth.py +233 -0
- mannf/product/billing/tenant_manager.py +873 -0
- mannf/product/cli.py +3900 -0
- mannf/product/cli_admin.py +408 -0
- mannf/product/dashboard/__init__.py +61 -0
- mannf/product/dashboard/app.py +3567 -0
- mannf/product/dashboard/models.py +460 -0
- mannf/product/dashboard/static/index.html +6347 -0
- mannf/product/dashboard/static/manifest.json +25 -0
- mannf/product/dashboard/static/pwa-icon-192.png +0 -0
- mannf/product/dashboard/static/pwa-icon-512.png +0 -0
- mannf/product/dashboard/static/sw.js +64 -0
- mannf/product/dashboard/telemetry.py +547 -0
- mannf/product/database.py +145 -0
- mannf/product/demo.py +844 -0
- mannf/product/doctor.py +509 -0
- mannf/product/exporters/__init__.py +65 -0
- mannf/product/exporters/azuredevops_exporter.py +257 -0
- mannf/product/exporters/base.py +307 -0
- mannf/product/exporters/bugzilla_exporter.py +200 -0
- mannf/product/exporters/dedup.py +275 -0
- mannf/product/exporters/finding_adapter.py +216 -0
- mannf/product/exporters/github_exporter.py +197 -0
- mannf/product/exporters/gitlab_exporter.py +215 -0
- mannf/product/exporters/jira_exporter.py +180 -0
- mannf/product/exporters/linear_exporter.py +195 -0
- mannf/product/exporters/loader.py +233 -0
- mannf/product/exporters/pagerduty_exporter.py +363 -0
- mannf/product/exporters/sentry_exporter.py +322 -0
- mannf/product/exporters/servicenow_exporter.py +240 -0
- mannf/product/exporters/shortcut_exporter.py +231 -0
- mannf/product/exporters/webhook_exporter.py +383 -0
- mannf/product/formatters/__init__.py +18 -0
- mannf/product/formatters/allure_formatter.py +161 -0
- mannf/product/formatters/ctrf_formatter.py +149 -0
- mannf/product/healing/__init__.py +30 -0
- mannf/product/healing/graphql_schema_diff.py +152 -0
- mannf/product/healing/healer.py +141 -0
- mannf/product/healing/models.py +175 -0
- mannf/product/healing/schema_diff.py +251 -0
- mannf/product/ingestors/__init__.py +77 -0
- mannf/product/ingestors/base.py +256 -0
- mannf/product/ingestors/bgstm_ingestor.py +764 -0
- mannf/product/ingestors/curl_ingestor.py +1019 -0
- mannf/product/ingestors/cypress_ingestor.py +487 -0
- mannf/product/ingestors/gherkin_ingestor.py +967 -0
- mannf/product/ingestors/graphql_ingestor.py +845 -0
- mannf/product/ingestors/grpc_ingestor.py +591 -0
- mannf/product/ingestors/har_ingestor.py +976 -0
- mannf/product/ingestors/loader.py +284 -0
- mannf/product/ingestors/models.py +146 -0
- mannf/product/ingestors/openapi_ingestor.py +606 -0
- mannf/product/ingestors/playwright_ingestor.py +449 -0
- mannf/product/ingestors/postman_ingestor.py +631 -0
- mannf/product/ingestors/traffic_ingestor.py +679 -0
- mannf/product/ingestors/websocket_ingestor.py +526 -0
- mannf/product/integrations/__init__.py +21 -0
- mannf/product/integrations/auth.py +190 -0
- mannf/product/integrations/graphql_parser.py +436 -0
- mannf/product/integrations/graphql_sut.py +247 -0
- mannf/product/integrations/grpc_sut.py +469 -0
- mannf/product/integrations/http_sut.py +237 -0
- mannf/product/integrations/kafka_adapter.py +342 -0
- mannf/product/integrations/openapi_parser.py +513 -0
- mannf/product/integrations/postman_parser.py +467 -0
- mannf/product/integrations/webhook_receiver.py +344 -0
- mannf/product/integrations/websocket_sut.py +434 -0
- mannf/product/llm/__init__.py +25 -0
- mannf/product/llm/anthropic_provider.py +94 -0
- mannf/product/llm/base.py +267 -0
- mannf/product/llm/config.py +48 -0
- mannf/product/llm/factory.py +42 -0
- mannf/product/llm/openai_provider.py +93 -0
- mannf/product/llm/prompts.py +403 -0
- mannf/product/llm/root_cause_service.py +311 -0
- mannf/product/llm/test_plan_models.py +78 -0
- mannf/product/metrics.py +149 -0
- mannf/product/middleware/__init__.py +3 -0
- mannf/product/middleware/audit_middleware.py +112 -0
- mannf/product/middleware/tenant_isolation.py +114 -0
- mannf/product/models.py +347 -0
- mannf/product/notifications/__init__.py +24 -0
- mannf/product/notifications/dispatcher.py +411 -0
- mannf/product/onboarding.py +190 -0
- mannf/product/orchestration/__init__.py +39 -0
- mannf/product/orchestration/ingest_scan_orchestrator.py +339 -0
- mannf/product/orchestration/pipeline.py +401 -0
- mannf/product/orchestrator.py +987 -0
- mannf/product/orchestrator_models.py +269 -0
- mannf/product/regression/__init__.py +36 -0
- mannf/product/regression/differ.py +172 -0
- mannf/product/regression/masking.py +100 -0
- mannf/product/regression/models.py +232 -0
- mannf/product/regression/recorder.py +124 -0
- mannf/product/regression/replayer.py +168 -0
- mannf/product/reports/__init__.py +10 -0
- mannf/product/reports/pdf.py +132 -0
- mannf/product/scheduling/__init__.py +57 -0
- mannf/product/scheduling/cron_utils.py +251 -0
- mannf/product/scheduling/engine.py +473 -0
- mannf/product/scheduling/models.py +86 -0
- mannf/product/scheduling/queue.py +894 -0
- mannf/product/scheduling/store.py +235 -0
- mannf/product/security/__init__.py +21 -0
- mannf/product/security/belief_guided.py +143 -0
- mannf/product/security/checks/__init__.py +55 -0
- mannf/product/security/checks/base.py +69 -0
- mannf/product/security/checks/bfla.py +77 -0
- mannf/product/security/checks/bola.py +77 -0
- mannf/product/security/checks/bopla.py +80 -0
- mannf/product/security/checks/broken_auth.py +86 -0
- mannf/product/security/checks/graphql_security.py +299 -0
- mannf/product/security/checks/inventory.py +70 -0
- mannf/product/security/checks/misconfig.py +158 -0
- mannf/product/security/checks/resource_consumption.py +70 -0
- mannf/product/security/checks/sensitive_flows.py +80 -0
- mannf/product/security/checks/ssrf.py +101 -0
- mannf/product/security/checks/unsafe_consumption.py +120 -0
- mannf/product/security/models.py +92 -0
- mannf/product/security/plugin_loader.py +182 -0
- mannf/product/security/reporter.py +92 -0
- mannf/product/security/scanner.py +183 -0
- mannf/product/server.py +6220 -0
- mannf/product/setup_wizard.py +873 -0
- mannf/product/status.py +404 -0
- mannf/product/storage/__init__.py +10 -0
- mannf/product/storage/artifact_store.py +343 -0
- mannf/product/telemetry.py +300 -0
- mannf/product/uninstall.py +169 -0
- mannf/product/upgrade.py +139 -0
- mannf/product/weights/__init__.py +13 -0
- mannf/product/weights/blob_store.py +299 -0
- mannf/product/weights/factory.py +42 -0
- mannf/product/weights/registry.py +159 -0
- mannf/product/weights/store.py +210 -0
- mannf/regression/__init__.py +7 -0
- mannf/regression/differ.py +9 -0
- mannf/regression/masking.py +9 -0
- mannf/regression/models.py +9 -0
- mannf/regression/recorder.py +9 -0
- mannf/regression/replayer.py +9 -0
- mannf/security/__init__.py +7 -0
- mannf/security/belief_guided.py +9 -0
- mannf/security/checks/__init__.py +7 -0
- mannf/security/checks/base.py +9 -0
- mannf/security/checks/bfla.py +9 -0
- mannf/security/checks/bola.py +9 -0
- mannf/security/checks/bopla.py +9 -0
- mannf/security/checks/broken_auth.py +9 -0
- mannf/security/checks/graphql_security.py +9 -0
- mannf/security/checks/inventory.py +9 -0
- mannf/security/checks/misconfig.py +9 -0
- mannf/security/checks/resource_consumption.py +9 -0
- mannf/security/checks/sensitive_flows.py +9 -0
- mannf/security/checks/ssrf.py +9 -0
- mannf/security/checks/unsafe_consumption.py +9 -0
- mannf/security/models.py +9 -0
- mannf/security/reporter.py +9 -0
- mannf/security/scanner.py +9 -0
- mannf/server.py +9 -0
- mannf/testing/__init__.py +7 -0
- mannf/testing/adaptive_controller.py +9 -0
- mannf/testing/models.py +9 -0
- mannf/weights/__init__.py +7 -0
- mannf/weights/registry.py +9 -0
- mannf/weights/store.py +9 -0
- nat_engine-1.dist-info/METADATA +555 -0
- nat_engine-1.dist-info/RECORD +299 -0
- nat_engine-1.dist-info/WHEEL +5 -0
- nat_engine-1.dist-info/entry_points.txt +4 -0
- nat_engine-1.dist-info/licenses/LICENSE +651 -0
- nat_engine-1.dist-info/licenses/NOTICE +178 -0
- nat_engine-1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
"""Weight snapshot registry.
|
|
7
|
+
|
|
8
|
+
:class:`WeightRegistry` maintains a JSON index file (default location:
|
|
9
|
+
``~/.nat/weight_registry.json``) that maps human-readable snapshot names to
|
|
10
|
+
file paths and optional metadata. This lets users refer to weight snapshots
|
|
11
|
+
by a stable name rather than a raw file path.
|
|
12
|
+
|
|
13
|
+
Index file format::
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
"version": "1.0",
|
|
17
|
+
"snapshots": {
|
|
18
|
+
"<name>": {
|
|
19
|
+
"path": "<absolute file path>",
|
|
20
|
+
"registered_at": "<ISO-8601 timestamp>",
|
|
21
|
+
"metadata": {<arbitrary dict>}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import json
|
|
30
|
+
import logging
|
|
31
|
+
import os
|
|
32
|
+
from datetime import datetime, timezone
|
|
33
|
+
from typing import Any, Dict, List, Optional
|
|
34
|
+
|
|
35
|
+
logger = logging.getLogger(__name__)
|
|
36
|
+
|
|
37
|
+
_DEFAULT_REGISTRY_PATH = os.path.join(
|
|
38
|
+
os.path.expanduser("~"), ".nat", "weight_registry.json"
|
|
39
|
+
)
|
|
40
|
+
_REGISTRY_VERSION = "1.0"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class WeightRegistry:
|
|
44
|
+
"""Persistent registry of named weight snapshots.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
index_path:
|
|
49
|
+
Path to the JSON index file. Defaults to ``~/.nat/weight_registry.json``.
|
|
50
|
+
The file and its parent directory are created on first write if they do
|
|
51
|
+
not exist.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, index_path: Optional[str] = None) -> None:
|
|
55
|
+
self._path = index_path if index_path is not None else _DEFAULT_REGISTRY_PATH
|
|
56
|
+
|
|
57
|
+
# ------------------------------------------------------------------
|
|
58
|
+
# Public API
|
|
59
|
+
# ------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
def register(
|
|
62
|
+
self,
|
|
63
|
+
name: str,
|
|
64
|
+
path: str,
|
|
65
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
66
|
+
) -> None:
|
|
67
|
+
"""Register a weight snapshot under *name*.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
name:
|
|
72
|
+
Human-readable identifier (must be unique; overwrites existing).
|
|
73
|
+
path:
|
|
74
|
+
Absolute or relative file path of the weight file.
|
|
75
|
+
metadata:
|
|
76
|
+
Optional arbitrary metadata dict (e.g. ``{"api": "petstore", "scans": 5}``).
|
|
77
|
+
"""
|
|
78
|
+
index = self._load_index()
|
|
79
|
+
index["snapshots"][name] = {
|
|
80
|
+
"path": os.path.abspath(path),
|
|
81
|
+
"registered_at": datetime.now(timezone.utc).isoformat(),
|
|
82
|
+
"metadata": metadata or {},
|
|
83
|
+
}
|
|
84
|
+
self._save_index(index)
|
|
85
|
+
logger.debug("WeightRegistry: registered %r → %s", name, path)
|
|
86
|
+
|
|
87
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
88
|
+
"""Return all registered snapshots as a list of dicts.
|
|
89
|
+
|
|
90
|
+
Each entry has keys ``name``, ``path``, ``registered_at``, and
|
|
91
|
+
``metadata``.
|
|
92
|
+
"""
|
|
93
|
+
index = self._load_index()
|
|
94
|
+
result = []
|
|
95
|
+
for name, info in index["snapshots"].items():
|
|
96
|
+
result.append({
|
|
97
|
+
"name": name,
|
|
98
|
+
"path": info["path"],
|
|
99
|
+
"registered_at": info["registered_at"],
|
|
100
|
+
"metadata": info.get("metadata", {}),
|
|
101
|
+
})
|
|
102
|
+
return sorted(result, key=lambda e: e["registered_at"])
|
|
103
|
+
|
|
104
|
+
def get(self, name: str) -> str:
|
|
105
|
+
"""Resolve *name* to its file path.
|
|
106
|
+
|
|
107
|
+
Raises
|
|
108
|
+
------
|
|
109
|
+
KeyError
|
|
110
|
+
If *name* is not registered.
|
|
111
|
+
"""
|
|
112
|
+
index = self._load_index()
|
|
113
|
+
if name not in index["snapshots"]:
|
|
114
|
+
raise KeyError(f"Weight snapshot {name!r} not registered")
|
|
115
|
+
return index["snapshots"][name]["path"]
|
|
116
|
+
|
|
117
|
+
def delete(self, name: str) -> None:
|
|
118
|
+
"""Remove the snapshot registered as *name*.
|
|
119
|
+
|
|
120
|
+
Does not delete the underlying weight file.
|
|
121
|
+
|
|
122
|
+
Raises
|
|
123
|
+
------
|
|
124
|
+
KeyError
|
|
125
|
+
If *name* is not registered.
|
|
126
|
+
"""
|
|
127
|
+
index = self._load_index()
|
|
128
|
+
if name not in index["snapshots"]:
|
|
129
|
+
raise KeyError(f"Weight snapshot {name!r} not registered")
|
|
130
|
+
del index["snapshots"][name]
|
|
131
|
+
self._save_index(index)
|
|
132
|
+
logger.debug("WeightRegistry: deleted %r", name)
|
|
133
|
+
|
|
134
|
+
# ------------------------------------------------------------------
|
|
135
|
+
# Internal helpers
|
|
136
|
+
# ------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
def _load_index(self) -> Dict[str, Any]:
|
|
139
|
+
"""Load the index file, returning an empty index if it does not exist."""
|
|
140
|
+
if not os.path.isfile(self._path):
|
|
141
|
+
return {"version": _REGISTRY_VERSION, "snapshots": {}}
|
|
142
|
+
try:
|
|
143
|
+
with open(self._path, encoding="utf-8") as fh:
|
|
144
|
+
data = json.load(fh)
|
|
145
|
+
if not isinstance(data, dict) or "snapshots" not in data:
|
|
146
|
+
logger.warning(
|
|
147
|
+
"WeightRegistry: corrupt index at %s, starting fresh", self._path
|
|
148
|
+
)
|
|
149
|
+
return {"version": _REGISTRY_VERSION, "snapshots": {}}
|
|
150
|
+
return data
|
|
151
|
+
except (json.JSONDecodeError, OSError) as exc:
|
|
152
|
+
logger.warning("WeightRegistry: could not read index %s: %s", self._path, exc)
|
|
153
|
+
return {"version": _REGISTRY_VERSION, "snapshots": {}}
|
|
154
|
+
|
|
155
|
+
def _save_index(self, index: Dict[str, Any]) -> None:
|
|
156
|
+
"""Persist *index* to disk, creating parent directories as needed."""
|
|
157
|
+
os.makedirs(os.path.dirname(os.path.abspath(self._path)), exist_ok=True)
|
|
158
|
+
with open(self._path, "w", encoding="utf-8") as fh:
|
|
159
|
+
json.dump(index, fh, indent=2)
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
"""Weight serialisation helpers.
|
|
7
|
+
|
|
8
|
+
:class:`WeightStore` provides JSON-based save/load for agent weight snapshots.
|
|
9
|
+
The on-disk format is::
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
"version": "1.0",
|
|
13
|
+
"saved_at": "<ISO-8601 timestamp>",
|
|
14
|
+
"agents": {
|
|
15
|
+
"<agent_id>": {
|
|
16
|
+
"role": "<role string>",
|
|
17
|
+
"layers": [{"W": [...], "b": [...]}, ...]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
numpy arrays are converted to nested Python lists for JSON compatibility and
|
|
23
|
+
restored to ``np.ndarray`` on load.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
import logging
|
|
30
|
+
import os
|
|
31
|
+
from datetime import datetime, timezone
|
|
32
|
+
from typing import Any, Dict, List
|
|
33
|
+
|
|
34
|
+
import numpy as np
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
_FORMAT_VERSION = "1.0"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _layers_to_serialisable(layers: List[dict]) -> List[dict]:
|
|
42
|
+
"""Convert a list of ``{"W": ndarray, "b": ndarray}`` dicts to JSON-safe lists."""
|
|
43
|
+
result = []
|
|
44
|
+
for layer in layers:
|
|
45
|
+
result.append({
|
|
46
|
+
"W": layer["W"].tolist(),
|
|
47
|
+
"b": layer["b"].tolist(),
|
|
48
|
+
})
|
|
49
|
+
return result
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _layers_from_serialisable(layers: List[dict]) -> List[dict]:
|
|
53
|
+
"""Restore a list of layer dicts from JSON-loaded lists back to ndarrays."""
|
|
54
|
+
result = []
|
|
55
|
+
for layer in layers:
|
|
56
|
+
result.append({
|
|
57
|
+
"W": np.array(layer["W"], dtype=float),
|
|
58
|
+
"b": np.array(layer["b"], dtype=float),
|
|
59
|
+
})
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class WeightStore:
|
|
64
|
+
"""Serialise and deserialise agent weight snapshots to/from JSON files.
|
|
65
|
+
|
|
66
|
+
All methods are static so the class can be used without instantiation.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def save(path: str, agent_weights: Dict[str, Dict[str, Any]]) -> None:
|
|
71
|
+
"""Save all agent weights to *path*.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
path:
|
|
76
|
+
File path to write (created or overwritten).
|
|
77
|
+
agent_weights:
|
|
78
|
+
Mapping of ``agent_id`` → ``{"role": str, "layers": List[dict]}``.
|
|
79
|
+
Each layer dict must have ``"W"`` and ``"b"`` numpy arrays.
|
|
80
|
+
"""
|
|
81
|
+
agents_serialisable: Dict[str, Any] = {}
|
|
82
|
+
for agent_id, info in agent_weights.items():
|
|
83
|
+
agents_serialisable[agent_id] = {
|
|
84
|
+
"role": info.get("role", ""),
|
|
85
|
+
"layers": _layers_to_serialisable(info["layers"]),
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
payload = {
|
|
89
|
+
"version": _FORMAT_VERSION,
|
|
90
|
+
"saved_at": datetime.now(timezone.utc).isoformat(),
|
|
91
|
+
"agents": agents_serialisable,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
os.makedirs(os.path.dirname(os.path.abspath(path)), exist_ok=True)
|
|
95
|
+
with open(path, "w", encoding="utf-8") as fh:
|
|
96
|
+
json.dump(payload, fh, indent=2)
|
|
97
|
+
|
|
98
|
+
logger.info("Weights saved to %s (%d agents)", path, len(agent_weights))
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def load(path: str) -> Dict[str, Any]:
|
|
102
|
+
"""Load agent weights from *path*.
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
dict
|
|
107
|
+
``{"version": str, "saved_at": str, "agents": {agent_id: {"role": str, "layers": [...]}}}``
|
|
108
|
+
where each layer dict contains ``np.ndarray`` values for ``"W"`` and ``"b"``.
|
|
109
|
+
|
|
110
|
+
Raises
|
|
111
|
+
------
|
|
112
|
+
FileNotFoundError
|
|
113
|
+
If *path* does not exist.
|
|
114
|
+
ValueError
|
|
115
|
+
If the file cannot be parsed or fails structure validation.
|
|
116
|
+
"""
|
|
117
|
+
if not os.path.isfile(path):
|
|
118
|
+
raise FileNotFoundError(f"Weight file not found: {path!r}")
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
with open(path, encoding="utf-8") as fh:
|
|
122
|
+
data = json.load(fh)
|
|
123
|
+
except json.JSONDecodeError as exc:
|
|
124
|
+
raise ValueError(f"Corrupt weight file {path!r}: {exc}") from exc
|
|
125
|
+
|
|
126
|
+
WeightStore._validate_structure(data)
|
|
127
|
+
|
|
128
|
+
agents_out: Dict[str, Any] = {}
|
|
129
|
+
for agent_id, info in data["agents"].items():
|
|
130
|
+
agents_out[agent_id] = {
|
|
131
|
+
"role": info.get("role", ""),
|
|
132
|
+
"layers": _layers_from_serialisable(info["layers"]),
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
"version": data["version"],
|
|
137
|
+
"saved_at": data["saved_at"],
|
|
138
|
+
"agents": agents_out,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
def save_single(path: str, agent_id: str, role: str, weights: List[dict]) -> None:
|
|
143
|
+
"""Save a single agent's weights to *path*.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
path:
|
|
148
|
+
File path to write.
|
|
149
|
+
agent_id:
|
|
150
|
+
Agent identifier stored in the file.
|
|
151
|
+
role:
|
|
152
|
+
Human-readable role label (e.g. ``"planner"``).
|
|
153
|
+
weights:
|
|
154
|
+
List of ``{"W": ndarray, "b": ndarray}`` layer dicts.
|
|
155
|
+
"""
|
|
156
|
+
WeightStore.save(path, {agent_id: {"role": role, "layers": weights}})
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def load_single(path: str) -> Dict[str, Any]:
|
|
160
|
+
"""Load a single-agent weight file written by :meth:`save_single`.
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
dict
|
|
165
|
+
``{"agent_id": str, "role": str, "layers": List[dict]}``
|
|
166
|
+
|
|
167
|
+
Raises
|
|
168
|
+
------
|
|
169
|
+
ValueError
|
|
170
|
+
If the file contains weights for more than one agent.
|
|
171
|
+
"""
|
|
172
|
+
data = WeightStore.load(path)
|
|
173
|
+
agents = data["agents"]
|
|
174
|
+
if len(agents) != 1:
|
|
175
|
+
raise ValueError(
|
|
176
|
+
f"load_single expects exactly one agent in {path!r}, found {len(agents)}"
|
|
177
|
+
)
|
|
178
|
+
agent_id, info = next(iter(agents.items()))
|
|
179
|
+
return {
|
|
180
|
+
"agent_id": agent_id,
|
|
181
|
+
"role": info["role"],
|
|
182
|
+
"layers": info["layers"],
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# ------------------------------------------------------------------
|
|
186
|
+
# Internal helpers
|
|
187
|
+
# ------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
@staticmethod
|
|
190
|
+
def _validate_structure(data: Any) -> None:
|
|
191
|
+
"""Raise :class:`ValueError` if *data* does not match the expected schema."""
|
|
192
|
+
if not isinstance(data, dict):
|
|
193
|
+
raise ValueError("Weight file root must be a JSON object")
|
|
194
|
+
if data.get("version") != _FORMAT_VERSION:
|
|
195
|
+
raise ValueError(
|
|
196
|
+
f"Unsupported weight file version {data.get('version')!r} "
|
|
197
|
+
f"(expected {_FORMAT_VERSION!r})"
|
|
198
|
+
)
|
|
199
|
+
if "agents" not in data or not isinstance(data["agents"], dict):
|
|
200
|
+
raise ValueError("Weight file missing 'agents' mapping")
|
|
201
|
+
for agent_id, info in data["agents"].items():
|
|
202
|
+
if not isinstance(info, dict):
|
|
203
|
+
raise ValueError(f"Agent entry {agent_id!r} is not a dict")
|
|
204
|
+
if "layers" not in info or not isinstance(info["layers"], list):
|
|
205
|
+
raise ValueError(f"Agent {agent_id!r} missing 'layers' list")
|
|
206
|
+
for i, layer in enumerate(info["layers"]):
|
|
207
|
+
if not isinstance(layer, dict) or "W" not in layer or "b" not in layer:
|
|
208
|
+
raise ValueError(
|
|
209
|
+
f"Agent {agent_id!r} layer {i} must have 'W' and 'b' keys"
|
|
210
|
+
)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression
|
|
7
|
+
from mannf.product.regression import * # noqa: F401, F403
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression.differ
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.regression.differ as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression.masking
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.regression.masking as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression.models
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.regression.models as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression.recorder
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.regression.recorder as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.regression.replayer
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.regression.replayer as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security
|
|
7
|
+
from mannf.product.security import * # noqa: F401, F403
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.belief_guided
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.belief_guided as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks
|
|
7
|
+
from mannf.product.security.checks import * # noqa: F401, F403
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.base
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.base as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.bfla
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.bfla as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.bola
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.bola as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.bopla
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.bopla as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.broken_auth
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.broken_auth as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.graphql_security
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.graphql_security as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.inventory
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.inventory as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.misconfig
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.misconfig as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.resource_consumption
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.resource_consumption as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.sensitive_flows
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.sensitive_flows as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.ssrf
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.ssrf as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.checks.unsafe_consumption
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.checks.unsafe_consumption as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
mannf/security/models.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.models
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.models as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.reporter
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.reporter as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.security.scanner
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.security.scanner as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
mannf/server.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.product.server
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.product.server as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.core.testing
|
|
7
|
+
from mannf.core.testing import * # noqa: F401, F403
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.core.testing.adaptive_controller
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.core.testing.adaptive_controller as _real
|
|
9
|
+
sys.modules[__name__] = _real
|
mannf/testing/models.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright (C) 2026 Brad Guider
|
|
2
|
+
# This file is part of NAT (Neural Agent Testing Framework).
|
|
3
|
+
# Licensed under the AGPL-3.0. See LICENSE for details.
|
|
4
|
+
# Commercial licensing available — see COMMERCIAL_LICENSE.md.
|
|
5
|
+
|
|
6
|
+
# Backward-compatible shim — source of truth has moved to mannf.core.testing.models
|
|
7
|
+
import sys
|
|
8
|
+
import mannf.core.testing.models as _real
|
|
9
|
+
sys.modules[__name__] = _real
|