coreason-manifest 0.9.0__py3-none-any.whl → 0.12.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 (30) hide show
  1. coreason_manifest/__init__.py +47 -13
  2. coreason_manifest/common.py +64 -0
  3. coreason_manifest/governance.py +83 -0
  4. coreason_manifest/schemas/__init__.py +9 -1
  5. coreason_manifest/schemas/coreason-v2.schema.json +462 -0
  6. coreason_manifest/utils/__init__.py +10 -0
  7. coreason_manifest/utils/logger.py +10 -0
  8. coreason_manifest/v2/__init__.py +1 -0
  9. coreason_manifest/v2/governance.py +144 -0
  10. coreason_manifest/v2/io.py +132 -0
  11. coreason_manifest/v2/resolver.py +67 -0
  12. coreason_manifest/v2/spec/__init__.py +1 -0
  13. coreason_manifest/v2/spec/contracts.py +34 -0
  14. coreason_manifest/v2/spec/definitions.py +196 -0
  15. coreason_manifest/v2/validator.py +48 -0
  16. {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/METADATA +68 -29
  17. coreason_manifest-0.12.0.dist-info/RECORD +20 -0
  18. {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/WHEEL +1 -1
  19. coreason_manifest/definitions/__init__.py +0 -49
  20. coreason_manifest/definitions/agent.py +0 -292
  21. coreason_manifest/definitions/audit.py +0 -122
  22. coreason_manifest/definitions/events.py +0 -392
  23. coreason_manifest/definitions/message.py +0 -126
  24. coreason_manifest/definitions/simulation.py +0 -50
  25. coreason_manifest/definitions/topology.py +0 -255
  26. coreason_manifest/recipes.py +0 -76
  27. coreason_manifest/schemas/agent.schema.json +0 -849
  28. coreason_manifest-0.9.0.dist-info/RECORD +0 -18
  29. {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/licenses/LICENSE +0 -0
  30. {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coreason_manifest
3
- Version: 0.9.0
3
+ Version: 0.12.0
4
4
  Summary: This package is the definitive source of truth. If it isn't in the manifest, it doesn't exist. If it violates the manifest, it doesn't run.
5
5
  License: # The Prosperity Public License 3.0.0
6
6
 
@@ -68,6 +68,7 @@ Classifier: License :: Other/Proprietary License
68
68
  Classifier: Programming Language :: Python :: 3.12
69
69
  Classifier: Operating System :: OS Independent
70
70
  Requires-Dist: coreason-identity (>=0.4.1,<0.5.0)
71
+ Requires-Dist: jsonschema (>=4.19.0,<5.0.0)
71
72
  Requires-Dist: loguru (>=0.7.2,<0.8.0)
72
73
  Requires-Dist: pydantic (>=2.12.5,<3.0.0)
73
74
  Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
@@ -87,17 +88,25 @@ The definitive source of truth for CoReason-AI Asset definitions. "The Blueprint
87
88
 
88
89
  ## Overview
89
90
 
90
- `coreason-manifest` acts as the validator for the "Agent Development Lifecycle" (ADLC). It ensures that every Agent produced meets strict GxP and security standards. If it isn't in the manifest, it doesn't exist. If it violates the manifest, it doesn't run.
91
+ `coreason-manifest` serves as the **Shared Kernel** for the Coreason ecosystem. It contains the canonical Pydantic definitions, schemas, and data structures for Agents and Workflows (Recipes).
92
+
93
+ It provides the **"Blueprint"** that all other services (Builder, Engine, Simulator) rely on. It focuses on strict typing, schema validation, and serialization, ensuring that if it isn't in the manifest, it doesn't exist.
94
+
95
+ ### Standards Clarification
96
+ *Note: The "Coreason Agent Manifest" (CAM) is a proprietary, strict governance schema designed for the CoReason Platform. It is distinct from the Oracle/Linux Foundation "Open Agent Specification," though we aim for future interoperability via adapters.*
91
97
 
92
98
  ## Features
93
99
 
94
- * **Open Agent Specification (OAS) Validation:** Parses and validates agent definitions against a strict schema.
95
- * **Compliance Enforcement:** Uses Open Policy Agent (OPA) / Rego to enforce complex business rules and allowlists.
96
- * **Integrity Verification:** Calculates and verifies SHA256 hashes of the agent's source code to prevent tampering.
97
- * **Automatic Schema Generation:** Inspects Python functions to generate Agent Interfaces, automatically handling `UserContext` injection.
98
- * **Dependency Pinning:** Enforces strict version pinning for all library dependencies.
99
- * **Trusted Bill of Materials (TBOM):** Validates libraries against an approved list.
100
- * **Compliance Microservice:** Can be run as a standalone API server (Service C) for centralized validation.
100
+ * **Coreason Agent Manifest (CAM):** Strict Pydantic models for Agent definitions (`AgentDefinition`) and Recipes (`Recipe`).
101
+ * **Strict Typing:** Enforces type safety for critical interfaces.
102
+ * **Governance & Policy:** Enforce organizational rules (domains, risk levels) on agents via `GovernanceConfig`.
103
+ * **Ergonomic Factory Methods:** Simplified construction of manifests.
104
+ * **Flexible Tooling:** Support for external tool definitions (`ToolDefinition`) and risk levels (`ToolRiskLevel`).
105
+ * **Topology Visualization:** Workflows are defined as graph topologies (`Workflow`).
106
+
107
+ ## Serialization & Base Model
108
+
109
+ Core definitions (e.g., `Manifest`, `Workflow`, `AgentDefinition`) inherit from Pydantic's `BaseModel`. Shared configuration models like `GovernanceConfig` inherit from `CoReasonBaseModel` for enhanced serialization capabilities.
101
110
 
102
111
  ## Installation
103
112
 
@@ -107,30 +116,60 @@ pip install coreason-manifest
107
116
 
108
117
  ## Usage
109
118
 
110
- `coreason-manifest` supports two modes: **Library (CLI)** and **Server (Microservice)**.
111
-
112
- ### 1. Library Usage
113
-
114
- Use the python library to validate local agent files and verify source integrity.
119
+ This library is used to define and validate Agent configurations programmatically.
115
120
 
116
121
  ```python
117
- from coreason_manifest import ManifestEngine, ManifestConfig
118
-
119
- # Initialize and Validate
120
- config = ManifestConfig(policy_path="./policies/compliance.rego")
121
- engine = ManifestEngine(config)
122
- agent_def = engine.load_and_validate("agent.yaml", "./src")
123
- ```
124
-
125
- ### 2. Server Mode
126
-
127
- Run the package as a FastAPI server to provide a centralized compliance API.
128
-
129
- ```bash
130
- uvicorn coreason_manifest.server:app --host 0.0.0.0 --port 8000
122
+ from coreason_manifest import (
123
+ Recipe,
124
+ ManifestMetadata,
125
+ AgentStep,
126
+ Workflow,
127
+ InterfaceDefinition,
128
+ StateDefinition,
129
+ PolicyDefinition
130
+ )
131
+
132
+ # 1. Define Metadata
133
+ metadata = ManifestMetadata(
134
+ name="Research Agent",
135
+ version="1.0.0"
136
+ )
137
+
138
+ # 2. Define Workflow
139
+ workflow = Workflow(
140
+ start="step1",
141
+ steps={
142
+ "step1": AgentStep(
143
+ id="step1",
144
+ agent="gpt-4-researcher",
145
+ next="step2"
146
+ ),
147
+ # ... define other steps
148
+ }
149
+ )
150
+
151
+ # 3. Instantiate Manifest
152
+ manifest = Recipe(
153
+ apiVersion="coreason.ai/v2",
154
+ kind="Recipe",
155
+ metadata=metadata,
156
+ interface=InterfaceDefinition(
157
+ inputs={"topic": {"type": "string"}},
158
+ outputs={"summary": {"type": "string"}}
159
+ ),
160
+ state=StateDefinition(),
161
+ policy=PolicyDefinition(max_retries=3),
162
+ workflow=workflow
163
+ )
164
+
165
+ print(f"Manifest '{manifest.metadata.name}' created successfully.")
131
166
  ```
132
167
 
133
168
  For full details, see the [Usage Documentation](docs/usage.md).
134
169
 
135
- For detailed requirements and architecture, please refer to the [Product Requirements](docs/product_requirements.md) or [Requirements](docs/requirements.md).
170
+ ## Documentation
171
+
172
+ * [Usage Guide](docs/usage.md): How to load and create manifests.
173
+ * [Governance & Policy Enforcement](docs/governance_policy_enforcement.md): Validating agents against organizational rules.
174
+ * [Coreason Agent Manifest (CAM)](docs/cap/specification.md): The Canonical YAML Authoring Format.
136
175
 
@@ -0,0 +1,20 @@
1
+ coreason_manifest/__init__.py,sha256=W74fAYQGapYpNq117NHIUeQvFddn22lJ4IxtMiVBtuE,1189
2
+ coreason_manifest/common.py,sha256=ebQPiWiYSKFVAS6eXUyOIgJbsO8QDXVlFQKtSCQLRzg,2136
3
+ coreason_manifest/governance.py,sha256=cR0q3TUbwTx2-ROGtVh9tP6o9XUiD2ekqoNsgCPDR2o,3299
4
+ coreason_manifest/schemas/__init__.py,sha256=g1cCu1DprGcnGAiuvYWz5VeKKXIHYYwlrsqdkg9fRZY,412
5
+ coreason_manifest/schemas/coreason-v2.schema.json,sha256=R2UqXEY1NSpNNtGpyJnjJ0jhnT4U6-2FKn-WPi4tnD0,11312
6
+ coreason_manifest/utils/__init__.py,sha256=Kdz519fMq6c7Px3MP5oD_9jfqqFbCiaHPBQTc0LhyII,848
7
+ coreason_manifest/utils/logger.py,sha256=dwvFVR2CuOjKsE0_59JsGqoIh8GpAwO6ATJDFt2SOlg,1640
8
+ coreason_manifest/v2/__init__.py,sha256=1bWTcGLOXjSDv2TgYXoH5wsla0T2W2ulhUHsK5AzIgM,23
9
+ coreason_manifest/v2/governance.py,sha256=nN2eu2YeASuDQglb35IOYm525LXWovMzAt9mba8loTY,5929
10
+ coreason_manifest/v2/io.py,sha256=6B5wzyW-TbnKcUgOOBaurSdZg0kQPtPx35hlcsbe1Us,4311
11
+ coreason_manifest/v2/resolver.py,sha256=lLPbNZcQjQ_GI71a7Rf-XiMM0CDgTy96nTLxm94gJLg,2313
12
+ coreason_manifest/v2/spec/__init__.py,sha256=i8Agxsn9vs6wGCaxaHVNupRpPCeAIGTtiA9FKyoJsaU,40
13
+ coreason_manifest/v2/spec/contracts.py,sha256=bDlYHDWlpSsIzDU8_fwXS2d0NjEHAPkIK3VpJbvcL7k,1354
14
+ coreason_manifest/v2/spec/definitions.py,sha256=TV2JHBBq90jN18xg5sG9Y_swd1blcXyomLb1H6DkpW4,8603
15
+ coreason_manifest/v2/validator.py,sha256=iTkpb_V38KbJ89h-Zne_1xep-XL44PS1PobZRnwV5K8,1504
16
+ coreason_manifest-0.12.0.dist-info/METADATA,sha256=R9MkpePi9F8sGa14-aNahaerSNOvZcFaAeiGVKcDZHg,8278
17
+ coreason_manifest-0.12.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
18
+ coreason_manifest-0.12.0.dist-info/licenses/LICENSE,sha256=3tYb7ZQe7sVXcbNmX22fDESFjOSIlCZodUGpZMkuSlk,3063
19
+ coreason_manifest-0.12.0.dist-info/licenses/NOTICE,sha256=tqzUyP9VTCGxoHLgBI0AC1i0G7m_PSyESFL8Jwuw0dA,610
20
+ coreason_manifest-0.12.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.3.0
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,49 +0,0 @@
1
- from .agent import AgentDefinition, AgentRuntimeConfig
2
- from .events import (
3
- ArtifactGenerated,
4
- ArtifactGeneratedPayload,
5
- CouncilVote,
6
- CouncilVotePayload,
7
- EdgeTraversed,
8
- EdgeTraversedPayload,
9
- GraphEvent,
10
- NodeCompleted,
11
- NodeCompletedPayload,
12
- NodeInit,
13
- # Export Aliases too
14
- NodeInitPayload,
15
- NodeRestored,
16
- NodeSkipped,
17
- NodeSkippedPayload,
18
- NodeStarted,
19
- NodeStartedPayload,
20
- NodeStream,
21
- NodeStreamPayload,
22
- WorkflowError,
23
- WorkflowErrorPayload,
24
- )
25
-
26
- __all__ = [
27
- "AgentRuntimeConfig",
28
- "AgentDefinition",
29
- "GraphEvent",
30
- "NodeInit",
31
- "NodeStarted",
32
- "NodeCompleted",
33
- "NodeRestored",
34
- "NodeSkipped",
35
- "NodeStream",
36
- "ArtifactGenerated",
37
- "EdgeTraversed",
38
- "CouncilVote",
39
- "WorkflowError",
40
- "NodeInitPayload",
41
- "NodeStartedPayload",
42
- "NodeCompletedPayload",
43
- "NodeSkippedPayload",
44
- "NodeStreamPayload",
45
- "EdgeTraversedPayload",
46
- "ArtifactGeneratedPayload",
47
- "CouncilVotePayload",
48
- "WorkflowErrorPayload",
49
- ]
@@ -1,292 +0,0 @@
1
- # Prosperity-3.0
2
- """Pydantic models for the Coreason Manifest system.
3
-
4
- These models define the structure and validation rules for the Agent Manifest
5
- (OAS). They represent the source of truth for Agent definitions.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- from datetime import datetime
11
- from enum import Enum
12
- from types import MappingProxyType
13
- from typing import Any, Dict, List, Mapping, Optional, Tuple
14
- from uuid import UUID
15
-
16
- from pydantic import (
17
- AfterValidator,
18
- AnyUrl,
19
- BaseModel,
20
- ConfigDict,
21
- Field,
22
- PlainSerializer,
23
- field_validator,
24
- model_validator,
25
- )
26
- from typing_extensions import Annotated
27
-
28
- from coreason_manifest.definitions.topology import Edge, Node
29
-
30
- # SemVer Regex pattern (simplified for standard SemVer)
31
- # Modified to accept optional 'v' or 'V' prefix (multiple allowed) for input normalization
32
- SEMVER_REGEX = (
33
- r"^[vV]*(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)"
34
- r"(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
35
- r"(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
36
- )
37
-
38
-
39
- def normalize_version(v: str) -> str:
40
- """Normalize version string by recursively stripping 'v' or 'V' prefix.
41
-
42
- Args:
43
- v: The version string to normalize.
44
-
45
- Returns:
46
- The normalized version string without 'v' prefix.
47
- """
48
- while v.lower().startswith("v"):
49
- v = v[1:]
50
- return v
51
-
52
-
53
- # Annotated type that validates SemVer regex (allowing multiple v) then normalizes to strict SemVer (no v)
54
- VersionStr = Annotated[
55
- str,
56
- Field(pattern=SEMVER_REGEX),
57
- AfterValidator(normalize_version),
58
- ]
59
-
60
- # Reusable immutable dictionary type
61
- ImmutableDict = Annotated[
62
- Mapping[str, Any],
63
- AfterValidator(lambda x: MappingProxyType(x)),
64
- PlainSerializer(lambda x: dict(x), return_type=Dict[str, Any]),
65
- ]
66
-
67
-
68
- # Strict URI type that serializes to string
69
- StrictUri = Annotated[
70
- AnyUrl,
71
- PlainSerializer(lambda x: str(x), return_type=str),
72
- ]
73
-
74
-
75
- class AgentMetadata(BaseModel):
76
- """Metadata for the Agent.
77
-
78
- Attributes:
79
- id: Unique Identifier for the Agent (UUID).
80
- version: Semantic Version of the Agent.
81
- name: Name of the Agent.
82
- author: Author of the Agent.
83
- created_at: Creation timestamp (ISO 8601).
84
- """
85
-
86
- model_config = ConfigDict(extra="forbid", frozen=True)
87
-
88
- id: UUID = Field(..., description="Unique Identifier for the Agent (UUID).")
89
- version: VersionStr = Field(..., description="Semantic Version of the Agent.")
90
- name: str = Field(..., min_length=1, description="Name of the Agent.")
91
- author: str = Field(..., min_length=1, description="Author of the Agent.")
92
- created_at: datetime = Field(..., description="Creation timestamp (ISO 8601).")
93
- requires_auth: bool = Field(default=False, description="Whether the agent requires user authentication.")
94
-
95
-
96
- class AgentInterface(BaseModel):
97
- """Interface definition for the Agent.
98
-
99
- Attributes:
100
- inputs: Typed arguments the agent accepts (JSON Schema).
101
- outputs: Typed structure of the result.
102
- """
103
-
104
- model_config = ConfigDict(extra="forbid", frozen=True)
105
-
106
- inputs: ImmutableDict = Field(..., description="Typed arguments the agent accepts (JSON Schema).")
107
- outputs: ImmutableDict = Field(..., description="Typed structure of the result.")
108
- injected_params: List[str] = Field(default_factory=list, description="List of parameters injected by the system.")
109
-
110
-
111
- class ModelConfig(BaseModel):
112
- """LLM Configuration parameters.
113
-
114
- Attributes:
115
- model: The LLM model identifier.
116
- temperature: Temperature for generation.
117
- """
118
-
119
- model_config = ConfigDict(extra="forbid", frozen=True)
120
-
121
- model: str = Field(..., description="The LLM model identifier.")
122
- temperature: float = Field(..., ge=0.0, le=2.0, description="Temperature for generation.")
123
-
124
-
125
- class AgentRuntimeConfig(BaseModel):
126
- """Configuration of the Agent execution.
127
-
128
- Attributes:
129
- nodes: A collection of execution units (Agents, Tools, Logic).
130
- edges: Directed connections defining control flow.
131
- entry_point: The ID of the starting node.
132
- llm_config: Specific LLM parameters.
133
- """
134
-
135
- model_config = ConfigDict(extra="forbid", frozen=True)
136
-
137
- nodes: List[Node] = Field(..., description="A collection of execution units.")
138
- edges: List[Edge] = Field(..., description="Directed connections defining control flow.")
139
- entry_point: str = Field(..., description="The ID of the starting node.")
140
- llm_config: ModelConfig = Field(..., alias="model_config", description="Specific LLM parameters.")
141
-
142
- @field_validator("nodes")
143
- @classmethod
144
- def validate_unique_node_ids(cls, v: List[Node]) -> List[Node]:
145
- """Ensure all node IDs are unique.
146
-
147
- Args:
148
- v: The list of nodes to validate.
149
-
150
- Returns:
151
- The validated list of nodes.
152
-
153
- Raises:
154
- ValueError: If duplicate node IDs are found.
155
- """
156
- ids = [node.id for node in v]
157
- if len(ids) != len(set(ids)):
158
- # Find duplicates
159
- seen = set()
160
- dupes = set()
161
- for x in ids:
162
- if x in seen:
163
- dupes.add(x)
164
- seen.add(x)
165
- raise ValueError(f"Duplicate node IDs found: {', '.join(dupes)}")
166
- return v
167
-
168
-
169
- class ToolRiskLevel(str, Enum):
170
- """Risk level for the tool."""
171
-
172
- SAFE = "safe"
173
- STANDARD = "standard"
174
- CRITICAL = "critical"
175
-
176
-
177
- class ToolRequirement(BaseModel):
178
- """Requirement for an MCP tool.
179
-
180
- Attributes:
181
- uri: The MCP endpoint URI.
182
- hash: Integrity check for the tool definition (SHA256).
183
- scopes: List of permissions required.
184
- risk_level: The risk level of the tool.
185
- """
186
-
187
- model_config = ConfigDict(extra="forbid", frozen=True)
188
-
189
- uri: StrictUri = Field(..., description="The MCP endpoint URI.")
190
- hash: str = Field(
191
- ..., pattern=r"^[a-fA-F0-9]{64}$", description="Integrity check for the tool definition (SHA256)."
192
- )
193
- scopes: List[str] = Field(..., description="List of permissions required.")
194
- risk_level: ToolRiskLevel = Field(..., description="The risk level of the tool.")
195
-
196
-
197
- class AgentDependencies(BaseModel):
198
- """External dependencies for the Agent.
199
-
200
- Attributes:
201
- tools: List of MCP tool requirements.
202
- libraries: List of Python packages required (if code execution is allowed).
203
- """
204
-
205
- model_config = ConfigDict(extra="forbid", frozen=True)
206
-
207
- tools: List[ToolRequirement] = Field(default_factory=list, description="List of MCP tool requirements.")
208
- libraries: Tuple[str, ...] = Field(
209
- default_factory=tuple, description="List of Python packages required (if code execution is allowed)."
210
- )
211
-
212
-
213
- class PolicyConfig(BaseModel):
214
- """Governance policy configuration.
215
-
216
- Attributes:
217
- budget_caps: Dictionary defining budget limits (e.g., {"total_cost": 10.0, "total_tokens": 1000}).
218
- human_in_the_loop: List of Node IDs that require human approval.
219
- allowed_domains: List of allowed domains for external access.
220
- """
221
-
222
- model_config = ConfigDict(extra="forbid", frozen=True)
223
-
224
- budget_caps: Dict[str, float] = Field(default_factory=dict, description="Budget limits.")
225
- human_in_the_loop: List[str] = Field(default_factory=list, description="Node IDs requiring human approval.")
226
- allowed_domains: List[str] = Field(default_factory=list, description="Allowed domains for external access.")
227
-
228
-
229
- class TraceLevel(str, Enum):
230
- """Level of tracing detail."""
231
-
232
- FULL = "full"
233
- METADATA_ONLY = "metadata_only"
234
- NONE = "none"
235
-
236
-
237
- class ObservabilityConfig(BaseModel):
238
- """Observability configuration.
239
-
240
- Attributes:
241
- trace_level: Level of tracing detail.
242
- retention_policy: Retention policy identifier (e.g., '30_days').
243
- encryption_key_id: Optional ID of the key used for log encryption.
244
- """
245
-
246
- model_config = ConfigDict(extra="forbid", frozen=True)
247
-
248
- trace_level: TraceLevel = Field(default=TraceLevel.FULL, description="Level of tracing detail.")
249
- retention_policy: str = Field(default="30_days", description="Retention policy identifier.")
250
- encryption_key_id: Optional[str] = Field(None, description="Optional ID of the key used for log encryption.")
251
-
252
-
253
- class AgentDefinition(BaseModel):
254
- """The Root Object for the CoReason Agent Manifest.
255
-
256
- Attributes:
257
- metadata: Metadata for the Agent.
258
- interface: Interface definition for the Agent.
259
- config: Configuration of the Agent execution.
260
- dependencies: External dependencies for the Agent.
261
- integrity_hash: SHA256 hash of the source code.
262
- """
263
-
264
- model_config = ConfigDict(
265
- extra="forbid",
266
- frozen=True,
267
- title="CoReason Agent Manifest",
268
- json_schema_extra={
269
- "$id": "https://coreason.ai/schemas/agent.schema.json",
270
- "description": "The definitive source of truth for CoReason Agent definitions.",
271
- },
272
- )
273
-
274
- metadata: AgentMetadata
275
- interface: AgentInterface
276
- config: AgentRuntimeConfig
277
- dependencies: AgentDependencies
278
- policy: Optional[PolicyConfig] = Field(None, description="Governance policy configuration.")
279
- observability: Optional[ObservabilityConfig] = Field(None, description="Observability configuration.")
280
- integrity_hash: str = Field(
281
- ...,
282
- pattern=r"^[a-fA-F0-9]{64}$",
283
- description="SHA256 hash of the source code.",
284
- )
285
-
286
- @model_validator(mode="after")
287
- def validate_auth_requirements(self) -> AgentDefinition:
288
- """Validate that agents requiring auth have user_context injected."""
289
- if self.metadata.requires_auth:
290
- if "user_context" not in self.interface.injected_params:
291
- raise ValueError("Agent requires authentication but 'user_context' is not an injected parameter.")
292
- return self
@@ -1,122 +0,0 @@
1
- import hashlib
2
- import json
3
- from datetime import datetime
4
- from enum import Enum
5
- from typing import Any, Dict, List, Optional
6
- from uuid import UUID
7
-
8
- from pydantic import BaseModel, ConfigDict, Field
9
-
10
- from .message import ChatMessage
11
-
12
-
13
- class GenAITokenUsage(BaseModel):
14
- """Token consumption stats aligned with OTel conventions."""
15
-
16
- model_config = ConfigDict(extra="ignore")
17
-
18
- input: int = Field(0, description="Number of input tokens (prompt).")
19
- output: int = Field(0, description="Number of output tokens (completion).")
20
- total: int = Field(0, description="Total number of tokens used.")
21
-
22
- # Backward compatibility fields (mapped to new fields in logic if needed, but kept for schema)
23
- prompt_tokens: int = 0
24
- completion_tokens: int = 0
25
- total_tokens: int = 0
26
- details: Dict[str, Any] = Field(default_factory=dict)
27
-
28
-
29
- class GenAIOperation(BaseModel):
30
- """An atomic operation in the reasoning process (e.g., one LLM call), aligning with OTel Spans."""
31
-
32
- model_config = ConfigDict(extra="ignore")
33
-
34
- span_id: str = Field(..., description="Unique identifier for the operation/span.")
35
- trace_id: str = Field(..., description="Trace ID this operation belongs to.")
36
- parent_id: Optional[str] = Field(None, description="Parent span ID.")
37
-
38
- operation_name: str = Field(..., description="Name of the operation (e.g., chat, embedding).")
39
- provider: str = Field(..., description="GenAI provider (e.g., openai, anthropic).")
40
- model: str = Field(..., description="Model name used.")
41
-
42
- start_time: datetime = Field(default_factory=datetime.now)
43
- end_time: Optional[datetime] = None
44
- duration_ms: float = 0.0
45
-
46
- # Context
47
- input_messages: List[ChatMessage] = Field(default_factory=list)
48
- output_messages: List[ChatMessage] = Field(default_factory=list)
49
-
50
- # Metrics
51
- token_usage: Optional[GenAITokenUsage] = None
52
-
53
- # Metadata
54
- status: str = "pending" # success, error
55
- error_type: Optional[str] = None
56
- metadata: Dict[str, Any] = Field(default_factory=dict)
57
-
58
-
59
- class ReasoningTrace(BaseModel):
60
- """The full audit trail of an Agent's execution session.
61
-
62
- Aligned with OpenTelemetry for trace identification.
63
- """
64
-
65
- model_config = ConfigDict(extra="ignore")
66
-
67
- trace_id: str = Field(..., description="Trace ID (OTel format).")
68
- agent_id: str
69
- session_id: Optional[str] = None
70
-
71
- start_time: datetime
72
- end_time: Optional[datetime] = None
73
-
74
- # The chain of thought (Ordered list of operations)
75
- steps: List[GenAIOperation] = Field(default_factory=list)
76
-
77
- # Final outcome
78
- status: str = "pending" # options: success, failure, pending
79
- final_result: Optional[str] = None
80
- error: Optional[str] = None
81
-
82
- # Aggregated stats
83
- total_tokens: GenAITokenUsage = Field(default_factory=GenAITokenUsage)
84
- total_cost: float = 0.0
85
-
86
-
87
- class AuditEventType(str, Enum):
88
- SYSTEM_CHANGE = "system_change"
89
- PREDICTION = "prediction"
90
- GUARDRAIL_TRIGGER = "guardrail_trigger"
91
-
92
-
93
- class AuditLog(BaseModel):
94
- """Tamper-evident legal record.
95
-
96
- IDs aligned with OpenTelemetry:
97
- - audit_id: Unique record ID.
98
- - trace_id: OTel Trace ID.
99
- """
100
-
101
- audit_id: UUID = Field(..., description="Unique identifier.")
102
- trace_id: str = Field(..., description="Trace ID for OTel correlation.")
103
- timestamp: datetime = Field(..., description="ISO8601 timestamp.")
104
- actor: str = Field(..., description="User ID or Agent Component ID.")
105
- event_type: AuditEventType = Field(..., description="Type of event.")
106
- safety_metadata: Dict[str, Any] = Field(..., description="Safety metadata (e.g., PII detected).")
107
- previous_hash: str = Field(..., description="Hash of the previous log entry.")
108
- integrity_hash: str = Field(..., description="SHA256 hash of this record + previous_hash.")
109
-
110
- def compute_hash(self) -> str:
111
- """Computes the integrity hash of the record."""
112
- # Use model_dump to get a dict, but exclude integrity_hash as it is the target
113
- data = self.model_dump(exclude={"integrity_hash"}, mode="json")
114
- # Ensure deterministic serialization
115
- json_str = json.dumps(data, sort_keys=True, default=str)
116
- return hashlib.sha256(json_str.encode("utf-8")).hexdigest()
117
-
118
-
119
- # --- Backward Compatibility ---
120
- # Adapters or Aliases
121
- CognitiveStep = GenAIOperation
122
- TokenUsage = GenAITokenUsage