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.
Files changed (337) hide show
  1. agent_control_plane/__init__.py +662 -0
  2. agent_control_plane/a2a_adapter.py +543 -0
  3. agent_control_plane/adapter.py +417 -0
  4. agent_control_plane/agent_hibernation.py +394 -0
  5. agent_control_plane/agent_kernel.py +470 -0
  6. agent_control_plane/compliance.py +720 -0
  7. agent_control_plane/constraint_graphs.py +478 -0
  8. agent_control_plane/control_plane.py +854 -0
  9. agent_control_plane/example_executors.py +195 -0
  10. agent_control_plane/execution_engine.py +231 -0
  11. agent_control_plane/flight_recorder.py +846 -0
  12. agent_control_plane/governance_layer.py +435 -0
  13. agent_control_plane/hf_utils.py +563 -0
  14. agent_control_plane/interfaces/__init__.py +55 -0
  15. agent_control_plane/interfaces/kernel_interface.py +361 -0
  16. agent_control_plane/interfaces/plugin_interface.py +497 -0
  17. agent_control_plane/interfaces/protocol_interfaces.py +387 -0
  18. agent_control_plane/kernel_space.py +1009 -0
  19. agent_control_plane/langchain_adapter.py +424 -0
  20. agent_control_plane/lifecycle.py +3113 -0
  21. agent_control_plane/mcp_adapter.py +653 -0
  22. agent_control_plane/ml_safety.py +563 -0
  23. agent_control_plane/multimodal.py +727 -0
  24. agent_control_plane/mute_agent.py +422 -0
  25. agent_control_plane/observability.py +787 -0
  26. agent_control_plane/orchestrator.py +482 -0
  27. agent_control_plane/plugin_registry.py +750 -0
  28. agent_control_plane/policy_engine.py +954 -0
  29. agent_control_plane/process_isolation.py +777 -0
  30. agent_control_plane/shadow_mode.py +310 -0
  31. agent_control_plane/signals.py +493 -0
  32. agent_control_plane/supervisor_agents.py +430 -0
  33. agent_control_plane/time_travel_debugger.py +557 -0
  34. agent_control_plane/tool_registry.py +452 -0
  35. agent_control_plane/vfs.py +697 -0
  36. agent_kernel/__init__.py +69 -0
  37. agent_kernel/analyzer.py +435 -0
  38. agent_kernel/auditor.py +36 -0
  39. agent_kernel/completeness_auditor.py +237 -0
  40. agent_kernel/detector.py +203 -0
  41. agent_kernel/kernel.py +744 -0
  42. agent_kernel/memory_manager.py +85 -0
  43. agent_kernel/models.py +374 -0
  44. agent_kernel/nudge_mechanism.py +263 -0
  45. agent_kernel/outcome_analyzer.py +338 -0
  46. agent_kernel/patcher.py +582 -0
  47. agent_kernel/semantic_analyzer.py +316 -0
  48. agent_kernel/semantic_purge.py +349 -0
  49. agent_kernel/simulator.py +449 -0
  50. agent_kernel/teacher.py +85 -0
  51. agent_kernel/triage.py +152 -0
  52. agent_os/__init__.py +409 -0
  53. agent_os/_adversarial_impl.py +200 -0
  54. agent_os/_circuit_breaker_impl.py +232 -0
  55. agent_os/_mcp_metrics.py +193 -0
  56. agent_os/adversarial.py +20 -0
  57. agent_os/agents_compat.py +490 -0
  58. agent_os/audit_logger.py +135 -0
  59. agent_os/base_agent.py +651 -0
  60. agent_os/circuit_breaker.py +34 -0
  61. agent_os/cli/__init__.py +659 -0
  62. agent_os/cli/cmd_audit.py +128 -0
  63. agent_os/cli/cmd_init.py +152 -0
  64. agent_os/cli/cmd_policy.py +41 -0
  65. agent_os/cli/cmd_policy_gen.py +180 -0
  66. agent_os/cli/cmd_validate.py +258 -0
  67. agent_os/cli/mcp_scan.py +265 -0
  68. agent_os/cli/output.py +192 -0
  69. agent_os/cli/policy_checker.py +330 -0
  70. agent_os/compat.py +74 -0
  71. agent_os/constraint_graph.py +234 -0
  72. agent_os/content_governance.py +140 -0
  73. agent_os/context_budget.py +305 -0
  74. agent_os/credential_redactor.py +224 -0
  75. agent_os/diff_policy.py +89 -0
  76. agent_os/egress_policy.py +159 -0
  77. agent_os/escalation.py +276 -0
  78. agent_os/event_bus.py +124 -0
  79. agent_os/exceptions.py +180 -0
  80. agent_os/execution_context_policy.py +141 -0
  81. agent_os/github_enterprise.py +96 -0
  82. agent_os/health.py +20 -0
  83. agent_os/integrations/__init__.py +279 -0
  84. agent_os/integrations/a2a_adapter.py +279 -0
  85. agent_os/integrations/agent_lightning/__init__.py +30 -0
  86. agent_os/integrations/anthropic_adapter.py +420 -0
  87. agent_os/integrations/autogen_adapter.py +620 -0
  88. agent_os/integrations/base.py +1137 -0
  89. agent_os/integrations/compat.py +229 -0
  90. agent_os/integrations/config.py +98 -0
  91. agent_os/integrations/conversation_guardian.py +957 -0
  92. agent_os/integrations/crewai_adapter.py +467 -0
  93. agent_os/integrations/drift_detector.py +425 -0
  94. agent_os/integrations/dry_run.py +124 -0
  95. agent_os/integrations/escalation.py +582 -0
  96. agent_os/integrations/gemini_adapter.py +364 -0
  97. agent_os/integrations/google_adk_adapter.py +633 -0
  98. agent_os/integrations/guardrails_adapter.py +394 -0
  99. agent_os/integrations/health.py +197 -0
  100. agent_os/integrations/langchain_adapter.py +654 -0
  101. agent_os/integrations/llamafirewall.py +343 -0
  102. agent_os/integrations/llamaindex_adapter.py +188 -0
  103. agent_os/integrations/logging.py +191 -0
  104. agent_os/integrations/maf_adapter.py +631 -0
  105. agent_os/integrations/mistral_adapter.py +365 -0
  106. agent_os/integrations/openai_adapter.py +816 -0
  107. agent_os/integrations/openai_agents_sdk.py +406 -0
  108. agent_os/integrations/policy_compose.py +171 -0
  109. agent_os/integrations/profiling.py +144 -0
  110. agent_os/integrations/pydantic_ai_adapter.py +420 -0
  111. agent_os/integrations/rate_limiter.py +130 -0
  112. agent_os/integrations/rbac.py +143 -0
  113. agent_os/integrations/registry.py +113 -0
  114. agent_os/integrations/scope_guard.py +303 -0
  115. agent_os/integrations/semantic_kernel_adapter.py +769 -0
  116. agent_os/integrations/smolagents_adapter.py +629 -0
  117. agent_os/integrations/templates.py +178 -0
  118. agent_os/integrations/token_budget.py +134 -0
  119. agent_os/integrations/tool_aliases.py +190 -0
  120. agent_os/integrations/webhooks.py +177 -0
  121. agent_os/lite.py +208 -0
  122. agent_os/mcp_gateway.py +385 -0
  123. agent_os/mcp_message_signer.py +273 -0
  124. agent_os/mcp_protocols.py +161 -0
  125. agent_os/mcp_response_scanner.py +232 -0
  126. agent_os/mcp_security.py +924 -0
  127. agent_os/mcp_session_auth.py +231 -0
  128. agent_os/mcp_sliding_rate_limiter.py +184 -0
  129. agent_os/memory_guard.py +409 -0
  130. agent_os/metrics.py +134 -0
  131. agent_os/mute.py +428 -0
  132. agent_os/mute_agent.py +209 -0
  133. agent_os/policies/__init__.py +77 -0
  134. agent_os/policies/async_evaluator.py +275 -0
  135. agent_os/policies/backends.py +670 -0
  136. agent_os/policies/bridge.py +169 -0
  137. agent_os/policies/budget.py +85 -0
  138. agent_os/policies/cli.py +294 -0
  139. agent_os/policies/conflict_resolution.py +270 -0
  140. agent_os/policies/data_classification.py +252 -0
  141. agent_os/policies/evaluator.py +239 -0
  142. agent_os/policies/policy_schema.json +228 -0
  143. agent_os/policies/rate_limiting.py +145 -0
  144. agent_os/policies/schema.py +115 -0
  145. agent_os/policies/shared.py +331 -0
  146. agent_os/prompt_injection.py +694 -0
  147. agent_os/providers.py +182 -0
  148. agent_os/py.typed +0 -0
  149. agent_os/retry.py +81 -0
  150. agent_os/reversibility.py +251 -0
  151. agent_os/sandbox.py +432 -0
  152. agent_os/sandbox_provider.py +140 -0
  153. agent_os/secure_codegen.py +525 -0
  154. agent_os/security_skills.py +538 -0
  155. agent_os/semantic_policy.py +422 -0
  156. agent_os/server/__init__.py +15 -0
  157. agent_os/server/__main__.py +25 -0
  158. agent_os/server/app.py +277 -0
  159. agent_os/server/models.py +104 -0
  160. agent_os/shift_left_metrics.py +130 -0
  161. agent_os/stateless.py +742 -0
  162. agent_os/supervisor.py +148 -0
  163. agent_os/task_outcome.py +148 -0
  164. agent_os/transparency.py +181 -0
  165. agent_os/trust_root.py +128 -0
  166. agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
  167. agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
  168. agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
  169. agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
  170. agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
  171. agent_os_observability/__init__.py +27 -0
  172. agent_os_observability/dashboards.py +898 -0
  173. agent_os_observability/metrics.py +398 -0
  174. agent_os_observability/server.py +223 -0
  175. agent_os_observability/tracer.py +232 -0
  176. agent_primitives/__init__.py +24 -0
  177. agent_primitives/failures.py +84 -0
  178. agent_primitives/py.typed +0 -0
  179. amb_core/__init__.py +177 -0
  180. amb_core/adapters/__init__.py +57 -0
  181. amb_core/adapters/aws_sqs_broker.py +376 -0
  182. amb_core/adapters/azure_servicebus_broker.py +340 -0
  183. amb_core/adapters/kafka_broker.py +260 -0
  184. amb_core/adapters/nats_broker.py +285 -0
  185. amb_core/adapters/rabbitmq_broker.py +235 -0
  186. amb_core/adapters/redis_broker.py +262 -0
  187. amb_core/broker.py +145 -0
  188. amb_core/bus.py +481 -0
  189. amb_core/cloudevents.py +509 -0
  190. amb_core/dlq.py +345 -0
  191. amb_core/hf_utils.py +536 -0
  192. amb_core/memory_broker.py +410 -0
  193. amb_core/models.py +141 -0
  194. amb_core/persistence.py +529 -0
  195. amb_core/schema.py +294 -0
  196. amb_core/tracing.py +358 -0
  197. atr/__init__.py +640 -0
  198. atr/access.py +348 -0
  199. atr/composition.py +645 -0
  200. atr/decorator.py +357 -0
  201. atr/executor.py +384 -0
  202. atr/health.py +557 -0
  203. atr/hf_utils.py +449 -0
  204. atr/injection.py +422 -0
  205. atr/metrics.py +440 -0
  206. atr/policies.py +403 -0
  207. atr/py.typed +2 -0
  208. atr/registry.py +452 -0
  209. atr/schema.py +480 -0
  210. atr/tools/safe/__init__.py +75 -0
  211. atr/tools/safe/calculator.py +467 -0
  212. atr/tools/safe/datetime_tool.py +443 -0
  213. atr/tools/safe/file_reader.py +402 -0
  214. atr/tools/safe/http_client.py +316 -0
  215. atr/tools/safe/json_parser.py +374 -0
  216. atr/tools/safe/text_tool.py +537 -0
  217. atr/tools/safe/toolkit.py +175 -0
  218. caas/__init__.py +162 -0
  219. caas/api/__init__.py +7 -0
  220. caas/api/server.py +1328 -0
  221. caas/caching.py +834 -0
  222. caas/cli.py +210 -0
  223. caas/conversation.py +223 -0
  224. caas/decay.py +72 -0
  225. caas/detection/__init__.py +9 -0
  226. caas/detection/detector.py +238 -0
  227. caas/enrichment.py +130 -0
  228. caas/gateway/__init__.py +27 -0
  229. caas/gateway/trust_gateway.py +474 -0
  230. caas/hf_utils.py +479 -0
  231. caas/ingestion/__init__.py +23 -0
  232. caas/ingestion/processors.py +253 -0
  233. caas/ingestion/structure_parser.py +188 -0
  234. caas/models.py +356 -0
  235. caas/pragmatic_truth.py +444 -0
  236. caas/routing/__init__.py +10 -0
  237. caas/routing/heuristic_router.py +58 -0
  238. caas/storage/__init__.py +9 -0
  239. caas/storage/store.py +389 -0
  240. caas/triad.py +213 -0
  241. caas/tuning/__init__.py +9 -0
  242. caas/tuning/tuner.py +329 -0
  243. caas/vfs/__init__.py +14 -0
  244. caas/vfs/filesystem.py +452 -0
  245. cmvk/__init__.py +218 -0
  246. cmvk/audit.py +402 -0
  247. cmvk/benchmarks.py +478 -0
  248. cmvk/constitutional.py +904 -0
  249. cmvk/hf_utils.py +301 -0
  250. cmvk/metrics.py +473 -0
  251. cmvk/profiles.py +300 -0
  252. cmvk/py.typed +0 -0
  253. cmvk/types.py +12 -0
  254. cmvk/verification.py +956 -0
  255. emk/__init__.py +89 -0
  256. emk/causal.py +352 -0
  257. emk/hf_utils.py +421 -0
  258. emk/indexer.py +83 -0
  259. emk/py.typed +0 -0
  260. emk/schema.py +204 -0
  261. emk/sleep_cycle.py +347 -0
  262. emk/store.py +281 -0
  263. iatp/__init__.py +166 -0
  264. iatp/attestation.py +461 -0
  265. iatp/cli.py +317 -0
  266. iatp/hf_utils.py +472 -0
  267. iatp/ipc_pipes.py +580 -0
  268. iatp/main.py +412 -0
  269. iatp/models/__init__.py +447 -0
  270. iatp/policy_engine.py +337 -0
  271. iatp/py.typed +2 -0
  272. iatp/recovery.py +321 -0
  273. iatp/security/__init__.py +270 -0
  274. iatp/sidecar/__init__.py +519 -0
  275. iatp/telemetry/__init__.py +164 -0
  276. iatp/tests/__init__.py +1 -0
  277. iatp/tests/test_attestation.py +370 -0
  278. iatp/tests/test_cli.py +131 -0
  279. iatp/tests/test_ed25519_attestation.py +211 -0
  280. iatp/tests/test_models.py +130 -0
  281. iatp/tests/test_policy_engine.py +347 -0
  282. iatp/tests/test_recovery.py +281 -0
  283. iatp/tests/test_security.py +222 -0
  284. iatp/tests/test_sidecar.py +167 -0
  285. iatp/tests/test_telemetry.py +175 -0
  286. mcp_kernel_server/__init__.py +28 -0
  287. mcp_kernel_server/cli.py +274 -0
  288. mcp_kernel_server/resources.py +217 -0
  289. mcp_kernel_server/server.py +564 -0
  290. mcp_kernel_server/tools.py +1174 -0
  291. mute_agent/__init__.py +68 -0
  292. mute_agent/core/__init__.py +1 -0
  293. mute_agent/core/execution_agent.py +166 -0
  294. mute_agent/core/handshake_protocol.py +201 -0
  295. mute_agent/core/reasoning_agent.py +238 -0
  296. mute_agent/knowledge_graph/__init__.py +1 -0
  297. mute_agent/knowledge_graph/graph_elements.py +65 -0
  298. mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
  299. mute_agent/knowledge_graph/subgraph.py +224 -0
  300. mute_agent/listener/__init__.py +43 -0
  301. mute_agent/listener/adapters/__init__.py +31 -0
  302. mute_agent/listener/adapters/base_adapter.py +189 -0
  303. mute_agent/listener/adapters/caas_adapter.py +344 -0
  304. mute_agent/listener/adapters/control_plane_adapter.py +436 -0
  305. mute_agent/listener/adapters/iatp_adapter.py +332 -0
  306. mute_agent/listener/adapters/scak_adapter.py +251 -0
  307. mute_agent/listener/listener.py +610 -0
  308. mute_agent/listener/state_observer.py +436 -0
  309. mute_agent/listener/threshold_config.py +313 -0
  310. mute_agent/super_system/__init__.py +1 -0
  311. mute_agent/super_system/router.py +204 -0
  312. mute_agent/visualization/__init__.py +10 -0
  313. mute_agent/visualization/graph_debugger.py +502 -0
  314. nexus/README.md +60 -0
  315. nexus/__init__.py +51 -0
  316. nexus/arbiter.py +359 -0
  317. nexus/client.py +466 -0
  318. nexus/dmz.py +444 -0
  319. nexus/escrow.py +430 -0
  320. nexus/exceptions.py +286 -0
  321. nexus/pyproject.toml +36 -0
  322. nexus/registry.py +393 -0
  323. nexus/reputation.py +425 -0
  324. nexus/schemas/__init__.py +51 -0
  325. nexus/schemas/compliance.py +276 -0
  326. nexus/schemas/escrow.py +251 -0
  327. nexus/schemas/manifest.py +225 -0
  328. nexus/schemas/receipt.py +208 -0
  329. nexus/tests/__init__.py +0 -0
  330. nexus/tests/conftest.py +146 -0
  331. nexus/tests/test_arbiter.py +192 -0
  332. nexus/tests/test_dmz.py +194 -0
  333. nexus/tests/test_escrow.py +276 -0
  334. nexus/tests/test_exceptions.py +225 -0
  335. nexus/tests/test_registry.py +232 -0
  336. nexus/tests/test_reputation.py +328 -0
  337. nexus/tests/test_schemas.py +295 -0
@@ -0,0 +1,225 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Agent Manifest Schema
5
+
6
+ Defines the complete identity and capability manifest for Nexus registration.
7
+ Extends the IATP manifest (RFC-001) with Nexus-specific fields.
8
+ """
9
+
10
+ from datetime import datetime, timezone
11
+ from typing import Literal, Optional
12
+ from pydantic import BaseModel, Field, field_validator
13
+ import re
14
+
15
+
16
+ class AgentIdentity(BaseModel):
17
+ """Decentralized identity for an agent."""
18
+
19
+ did: str = Field(
20
+ ...,
21
+ description="Decentralized Identifier (did:nexus:...)",
22
+ examples=["did:nexus:carbon-auditor-v1.2.0"]
23
+ )
24
+ verification_key: str = Field(
25
+ ...,
26
+ description="Ed25519 public key (base64 encoded)",
27
+ examples=["ed25519:abc123..."]
28
+ )
29
+ owner_id: str = Field(
30
+ ...,
31
+ description="Developer/Organization ID"
32
+ )
33
+ display_name: Optional[str] = Field(
34
+ None,
35
+ description="Human-readable agent name"
36
+ )
37
+ contact: Optional[str] = Field(
38
+ None,
39
+ description="Contact email for security issues"
40
+ )
41
+
42
+ @field_validator("did")
43
+ @classmethod
44
+ def validate_did(cls, v: str) -> str:
45
+ """Validate DID format."""
46
+ if not v.startswith("did:nexus:"):
47
+ raise ValueError("DID must start with 'did:nexus:'")
48
+ return v
49
+
50
+ @field_validator("verification_key")
51
+ @classmethod
52
+ def validate_key(cls, v: str) -> str:
53
+ """Validate verification key format."""
54
+ if not v.startswith("ed25519:"):
55
+ raise ValueError("Verification key must be Ed25519 format")
56
+ return v
57
+
58
+
59
+ class AgentCapabilities(BaseModel):
60
+ """What this agent can do."""
61
+
62
+ domains: list[str] = Field(
63
+ default_factory=list,
64
+ description="Capability domains (e.g., 'data-analysis', 'code-generation')"
65
+ )
66
+ tools: list[str] = Field(
67
+ default_factory=list,
68
+ description="Available tool names"
69
+ )
70
+ max_concurrency: int = Field(
71
+ default=10,
72
+ ge=1,
73
+ le=1000,
74
+ description="Maximum concurrent requests"
75
+ )
76
+ sla_latency_ms: int = Field(
77
+ default=5000,
78
+ ge=100,
79
+ le=300000,
80
+ description="SLA latency in milliseconds"
81
+ )
82
+ idempotency: bool = Field(
83
+ default=False,
84
+ description="Whether operations are idempotent"
85
+ )
86
+ reversibility: Literal["full", "partial", "none"] = Field(
87
+ default="partial",
88
+ description="Level of operation reversibility"
89
+ )
90
+ undo_window_seconds: Optional[int] = Field(
91
+ default=3600,
92
+ description="Time window for undo operations (if reversible)"
93
+ )
94
+
95
+
96
+ class AgentPrivacy(BaseModel):
97
+ """Privacy and data handling policies."""
98
+
99
+ retention_policy: Literal["ephemeral", "session", "permanent"] = Field(
100
+ default="ephemeral",
101
+ description="How long data is retained"
102
+ )
103
+ pii_handling: Literal["reject", "anonymize", "accept"] = Field(
104
+ default="reject",
105
+ description="How PII is handled"
106
+ )
107
+ human_in_loop: bool = Field(
108
+ default=False,
109
+ description="Whether human review is part of processing"
110
+ )
111
+ training_consent: bool = Field(
112
+ default=False,
113
+ description="Whether data may be used for training"
114
+ )
115
+ data_residency: Optional[str] = Field(
116
+ default=None,
117
+ description="Required data residency region (e.g., 'us', 'eu')"
118
+ )
119
+
120
+
121
+ class MuteRules(BaseModel):
122
+ """Agent OS Mute Agent rules attached to this agent."""
123
+
124
+ rule_hashes: list[str] = Field(
125
+ default_factory=list,
126
+ description="SHA-256 hashes of attached mute rules"
127
+ )
128
+ last_validated: Optional[datetime] = Field(
129
+ default=None,
130
+ description="When rules were last validated by Control Plane"
131
+ )
132
+ control_plane_signature: Optional[str] = Field(
133
+ default=None,
134
+ description="Control Plane signature of rule validation"
135
+ )
136
+
137
+
138
+ class AgentManifest(BaseModel):
139
+ """
140
+ Complete manifest for Nexus registration.
141
+
142
+ This extends the IATP manifest (RFC-001) with Nexus-specific fields
143
+ for the Trust Exchange.
144
+ """
145
+
146
+ schema_version: str = Field(
147
+ default="1.0",
148
+ description="Schema version for forward compatibility"
149
+ )
150
+ identity: AgentIdentity
151
+ capabilities: AgentCapabilities = Field(default_factory=AgentCapabilities)
152
+ privacy: AgentPrivacy = Field(default_factory=AgentPrivacy)
153
+ mute_rules: MuteRules = Field(default_factory=MuteRules)
154
+
155
+ # Nexus-specific fields
156
+ verification_level: Literal["verified_partner", "verified", "registered", "unknown"] = Field(
157
+ default="registered",
158
+ description="Verification tier on Nexus"
159
+ )
160
+ registered_at: Optional[datetime] = Field(
161
+ default=None,
162
+ description="When agent was registered on Nexus"
163
+ )
164
+ last_seen: Optional[datetime] = Field(
165
+ default=None,
166
+ description="Last activity timestamp"
167
+ )
168
+ trust_score: int = Field(
169
+ default=400,
170
+ ge=0,
171
+ le=1000,
172
+ description="Current trust score (0-1000)"
173
+ )
174
+
175
+ # Attestation
176
+ codebase_hash: Optional[str] = Field(
177
+ default=None,
178
+ description="SHA-256 hash of agent codebase"
179
+ )
180
+ config_hash: Optional[str] = Field(
181
+ default=None,
182
+ description="SHA-256 hash of agent configuration"
183
+ )
184
+ attestation_signature: Optional[str] = Field(
185
+ default=None,
186
+ description="Control Plane signature of attestation"
187
+ )
188
+ attestation_expires: Optional[datetime] = Field(
189
+ default=None,
190
+ description="When attestation expires"
191
+ )
192
+
193
+ def is_attestation_valid(self) -> bool:
194
+ """Check if attestation is present and not expired."""
195
+ if not self.attestation_signature or not self.attestation_expires:
196
+ return False
197
+ return datetime.now(timezone.utc) < self.attestation_expires
198
+
199
+ def to_iatp_manifest(self) -> dict:
200
+ """Convert to IATP-compatible manifest format."""
201
+ return {
202
+ "$schema": "https://agent-os.dev/iatp/v1/manifest.schema.json",
203
+ "identity": {
204
+ "agent_id": self.identity.did.replace("did:nexus:", ""),
205
+ "verification_key": self.identity.verification_key,
206
+ "owner": self.identity.owner_id,
207
+ "contact": self.identity.contact,
208
+ },
209
+ "trust_level": self.verification_level,
210
+ "capabilities": {
211
+ "idempotency": self.capabilities.idempotency,
212
+ "max_concurrency": self.capabilities.max_concurrency,
213
+ "sla_latency_ms": self.capabilities.sla_latency_ms,
214
+ },
215
+ "reversibility": {
216
+ "level": self.capabilities.reversibility,
217
+ "undo_window_seconds": self.capabilities.undo_window_seconds,
218
+ },
219
+ "privacy": {
220
+ "retention_policy": self.privacy.retention_policy,
221
+ "human_in_loop": self.privacy.human_in_loop,
222
+ "training_consent": self.privacy.training_consent,
223
+ },
224
+ "protocol_version": "1.0",
225
+ }
@@ -0,0 +1,208 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Job Receipt Schemas
5
+
6
+ Defines receipts for job completion and outcome verification.
7
+ """
8
+
9
+ from datetime import datetime
10
+ from typing import Literal, Optional, Any
11
+ from pydantic import BaseModel, Field
12
+ import hashlib
13
+ import json
14
+
15
+
16
+ class JobReceipt(BaseModel):
17
+ """Base receipt for a job/task between agents."""
18
+
19
+ receipt_id: str = Field(
20
+ ...,
21
+ description="Unique receipt identifier"
22
+ )
23
+ task_id: str = Field(
24
+ ...,
25
+ description="ID of the task being receipted"
26
+ )
27
+ requester_did: str = Field(
28
+ ...,
29
+ description="DID of the requesting agent"
30
+ )
31
+ provider_did: str = Field(
32
+ ...,
33
+ description="DID of the providing agent"
34
+ )
35
+ task_hash: str = Field(
36
+ ...,
37
+ description="SHA-256 hash of the task specification"
38
+ )
39
+ created_at: datetime = Field(
40
+ default_factory=datetime.utcnow,
41
+ description="When the receipt was created"
42
+ )
43
+
44
+ def compute_hash(self) -> str:
45
+ """Compute deterministic hash of receipt."""
46
+ data = {
47
+ "receipt_id": self.receipt_id,
48
+ "task_id": self.task_id,
49
+ "requester_did": self.requester_did,
50
+ "provider_did": self.provider_did,
51
+ "task_hash": self.task_hash,
52
+ "created_at": self.created_at.isoformat(),
53
+ }
54
+ canonical = json.dumps(data, sort_keys=True)
55
+ return hashlib.sha256(canonical.encode()).hexdigest()
56
+
57
+
58
+ class JobCompletionReceipt(JobReceipt):
59
+ """Receipt issued when a job is completed."""
60
+
61
+ outcome: Literal["success", "failure", "partial", "timeout"] = Field(
62
+ ...,
63
+ description="Outcome of the job"
64
+ )
65
+ completed_at: datetime = Field(
66
+ default_factory=datetime.utcnow,
67
+ description="When the job completed"
68
+ )
69
+ duration_ms: int = Field(
70
+ ...,
71
+ ge=0,
72
+ description="Duration of job execution in milliseconds"
73
+ )
74
+ output_hash: Optional[str] = Field(
75
+ default=None,
76
+ description="SHA-256 hash of the output (if any)"
77
+ )
78
+ error_code: Optional[str] = Field(
79
+ default=None,
80
+ description="Error code if outcome is failure"
81
+ )
82
+ error_message: Optional[str] = Field(
83
+ default=None,
84
+ description="Error message if outcome is failure"
85
+ )
86
+
87
+ # SCAK validation
88
+ scak_validated: bool = Field(
89
+ default=False,
90
+ description="Whether output was validated by SCAK"
91
+ )
92
+ scak_drift_score: Optional[float] = Field(
93
+ default=None,
94
+ ge=0.0,
95
+ le=1.0,
96
+ description="SCAK drift score (0=no drift, 1=complete drift)"
97
+ )
98
+ scak_threshold: Optional[float] = Field(
99
+ default=None,
100
+ description="Drift threshold used for validation"
101
+ )
102
+
103
+
104
+ class SignedReceipt(BaseModel):
105
+ """A receipt with cryptographic signatures from both parties."""
106
+
107
+ receipt: JobCompletionReceipt
108
+ receipt_hash: str = Field(
109
+ ...,
110
+ description="SHA-256 hash of the receipt"
111
+ )
112
+
113
+ # Signatures
114
+ requester_signature: Optional[str] = Field(
115
+ default=None,
116
+ description="Ed25519 signature from requester"
117
+ )
118
+ requester_signed_at: Optional[datetime] = Field(
119
+ default=None,
120
+ description="When requester signed"
121
+ )
122
+ provider_signature: Optional[str] = Field(
123
+ default=None,
124
+ description="Ed25519 signature from provider"
125
+ )
126
+ provider_signed_at: Optional[datetime] = Field(
127
+ default=None,
128
+ description="When provider signed"
129
+ )
130
+
131
+ # Nexus attestation
132
+ nexus_witnessed: bool = Field(
133
+ default=False,
134
+ description="Whether Nexus has witnessed this receipt"
135
+ )
136
+ nexus_signature: Optional[str] = Field(
137
+ default=None,
138
+ description="Nexus signature witnessing the receipt"
139
+ )
140
+ nexus_witnessed_at: Optional[datetime] = Field(
141
+ default=None,
142
+ description="When Nexus witnessed"
143
+ )
144
+
145
+ def is_fully_signed(self) -> bool:
146
+ """Check if both parties have signed."""
147
+ return bool(self.requester_signature and self.provider_signature)
148
+
149
+ def is_nexus_witnessed(self) -> bool:
150
+ """Check if Nexus has witnessed this receipt."""
151
+ return self.nexus_witnessed and bool(self.nexus_signature)
152
+
153
+
154
+ class DisputeReceipt(BaseModel):
155
+ """Receipt for a disputed job outcome."""
156
+
157
+ dispute_id: str = Field(
158
+ ...,
159
+ description="Unique dispute identifier"
160
+ )
161
+ original_receipt: Optional[SignedReceipt] = None
162
+
163
+ # Dispute details
164
+ disputing_party: Literal["requester", "provider"] = Field(
165
+ ...,
166
+ description="Which party raised the dispute"
167
+ )
168
+ dispute_reason: str = Field(
169
+ ...,
170
+ description="Reason for the dispute"
171
+ )
172
+ claimed_outcome: Literal["success", "failure", "partial"] = Field(
173
+ ...,
174
+ description="Outcome claimed by disputing party"
175
+ )
176
+
177
+ # Evidence
178
+ requester_logs_hash: Optional[str] = Field(
179
+ default=None,
180
+ description="Hash of requester's flight recorder logs"
181
+ )
182
+ provider_logs_hash: Optional[str] = Field(
183
+ default=None,
184
+ description="Hash of provider's flight recorder logs"
185
+ )
186
+
187
+ # Resolution
188
+ resolved: bool = Field(
189
+ default=False,
190
+ description="Whether dispute has been resolved"
191
+ )
192
+ resolution_outcome: Optional[Literal["requester_wins", "provider_wins", "split"]] = Field(
193
+ default=None,
194
+ description="Resolution outcome"
195
+ )
196
+ arbiter_decision: Optional[str] = Field(
197
+ default=None,
198
+ description="Arbiter's decision explanation"
199
+ )
200
+ resolved_at: Optional[datetime] = Field(
201
+ default=None,
202
+ description="When dispute was resolved"
203
+ )
204
+
205
+ created_at: datetime = Field(
206
+ default_factory=datetime.utcnow,
207
+ description="When dispute was raised"
208
+ )
File without changes
@@ -0,0 +1,146 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """Shared fixtures for Nexus tests."""
4
+
5
+ import os
6
+ import sys
7
+ from datetime import datetime, timedelta, timezone
8
+
9
+ import pytest
10
+
11
+ # Add parent of nexus package to path so 'nexus' is importable
12
+ _nexus_parent = os.path.join(os.path.dirname(__file__), "..", "..")
13
+ if _nexus_parent not in sys.path:
14
+ sys.path.insert(0, _nexus_parent)
15
+
16
+ from nexus.reputation import ReputationEngine, ReputationHistory, TrustScore, TrustTier
17
+ from nexus.escrow import EscrowManager
18
+ from nexus.schemas.manifest import (
19
+ AgentIdentity,
20
+ AgentCapabilities,
21
+ AgentPrivacy,
22
+ MuteRules,
23
+ AgentManifest,
24
+ )
25
+ from nexus.schemas.escrow import EscrowRequest, EscrowReceipt, EscrowStatus
26
+
27
+
28
+ @pytest.fixture
29
+ def reputation_engine():
30
+ """Create a ReputationEngine with default threshold."""
31
+ return ReputationEngine(trust_threshold=500)
32
+
33
+
34
+ @pytest.fixture
35
+ def escrow_manager(reputation_engine):
36
+ """Create an EscrowManager with a reputation engine."""
37
+ return EscrowManager(reputation_engine=reputation_engine)
38
+
39
+
40
+ @pytest.fixture
41
+ def sample_identity():
42
+ """Create a sample AgentIdentity."""
43
+ return AgentIdentity(
44
+ did="did:nexus:test-agent-v1",
45
+ verification_key="ed25519:testkey123abc",
46
+ owner_id="org-test-corp",
47
+ display_name="Test Agent",
48
+ contact="test@example.com",
49
+ )
50
+
51
+
52
+ @pytest.fixture
53
+ def sample_capabilities():
54
+ """Create sample AgentCapabilities."""
55
+ return AgentCapabilities(
56
+ domains=["data-analysis", "code-generation"],
57
+ tools=["python", "sql"],
58
+ max_concurrency=10,
59
+ sla_latency_ms=5000,
60
+ idempotency=True,
61
+ reversibility="full",
62
+ )
63
+
64
+
65
+ @pytest.fixture
66
+ def sample_privacy():
67
+ """Create sample AgentPrivacy."""
68
+ return AgentPrivacy(
69
+ retention_policy="ephemeral",
70
+ pii_handling="reject",
71
+ human_in_loop=False,
72
+ training_consent=False,
73
+ )
74
+
75
+
76
+ @pytest.fixture
77
+ def sample_manifest(sample_identity, sample_capabilities, sample_privacy):
78
+ """Create a sample AgentManifest."""
79
+ return AgentManifest(
80
+ identity=sample_identity,
81
+ capabilities=sample_capabilities,
82
+ privacy=sample_privacy,
83
+ verification_level="registered",
84
+ )
85
+
86
+
87
+ @pytest.fixture
88
+ def sample_history():
89
+ """Create a sample ReputationHistory."""
90
+ return ReputationHistory(
91
+ agent_did="did:nexus:test-agent-v1",
92
+ successful_tasks=10,
93
+ failed_tasks=1,
94
+ total_tasks=11,
95
+ disputes_won=2,
96
+ disputes_lost=0,
97
+ uptime_days=30,
98
+ last_activity=datetime.now(timezone.utc),
99
+ )
100
+
101
+
102
+ @pytest.fixture
103
+ def sample_escrow_request():
104
+ """Create a sample EscrowRequest."""
105
+ return EscrowRequest(
106
+ requester_did="did:nexus:requester-agent",
107
+ provider_did="did:nexus:provider-agent",
108
+ task_hash="abc123def456",
109
+ credits=100,
110
+ timeout_seconds=3600,
111
+ require_scak_validation=False,
112
+ )
113
+
114
+
115
+ def make_manifest(
116
+ did: str = "did:nexus:test-agent-v1",
117
+ owner_id: str = "org-test-corp",
118
+ verification_level: str = "registered",
119
+ domains: list[str] | None = None,
120
+ retention_policy: str = "ephemeral",
121
+ pii_handling: str = "reject",
122
+ training_consent: bool = False,
123
+ idempotency: bool = False,
124
+ reversibility: str = "partial",
125
+ trust_score: int = 400,
126
+ ) -> AgentManifest:
127
+ """Helper to create manifests with custom parameters."""
128
+ return AgentManifest(
129
+ identity=AgentIdentity(
130
+ did=did,
131
+ verification_key="ed25519:testkey123abc",
132
+ owner_id=owner_id,
133
+ ),
134
+ capabilities=AgentCapabilities(
135
+ domains=domains or ["data-analysis"],
136
+ idempotency=idempotency,
137
+ reversibility=reversibility,
138
+ ),
139
+ privacy=AgentPrivacy(
140
+ retention_policy=retention_policy,
141
+ pii_handling=pii_handling,
142
+ training_consent=training_consent,
143
+ ),
144
+ verification_level=verification_level,
145
+ trust_score=trust_score,
146
+ )