coreason-manifest 0.10.0__py3-none-any.whl → 0.13.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 (31) hide show
  1. coreason_manifest/__init__.py +35 -82
  2. coreason_manifest/{definitions/base.py → common.py} +18 -1
  3. coreason_manifest/governance.py +83 -0
  4. coreason_manifest/schemas/coreason-v2.schema.json +462 -0
  5. coreason_manifest/utils/logger.py +0 -45
  6. coreason_manifest/v2/__init__.py +1 -0
  7. coreason_manifest/v2/governance.py +144 -0
  8. coreason_manifest/v2/io.py +132 -0
  9. coreason_manifest/v2/resolver.py +67 -0
  10. coreason_manifest/v2/spec/__init__.py +1 -0
  11. coreason_manifest/v2/spec/contracts.py +34 -0
  12. coreason_manifest/v2/spec/definitions.py +196 -0
  13. coreason_manifest/v2/validator.py +48 -0
  14. {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/METADATA +48 -72
  15. coreason_manifest-0.13.0.dist-info/RECORD +20 -0
  16. coreason_manifest/definitions/__init__.py +0 -60
  17. coreason_manifest/definitions/agent.py +0 -370
  18. coreason_manifest/definitions/audit.py +0 -181
  19. coreason_manifest/definitions/events.py +0 -423
  20. coreason_manifest/definitions/message.py +0 -188
  21. coreason_manifest/definitions/simulation.py +0 -79
  22. coreason_manifest/definitions/simulation_config.py +0 -46
  23. coreason_manifest/definitions/topology.py +0 -341
  24. coreason_manifest/recipes.py +0 -84
  25. coreason_manifest/schemas/agent.schema.json +0 -1051
  26. coreason_manifest/schemas/recipe.schema.json +0 -813
  27. coreason_manifest/v1/__init__.py +0 -15
  28. coreason_manifest-0.10.0.dist-info/RECORD +0 -22
  29. {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/WHEEL +0 -0
  30. {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/licenses/LICENSE +0 -0
  31. {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.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.10.0
3
+ Version: 0.13.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
 
@@ -67,7 +67,7 @@ Requires-Python: >=3.12
67
67
  Classifier: License :: Other/Proprietary License
68
68
  Classifier: Programming Language :: Python :: 3.12
69
69
  Classifier: Operating System :: OS Independent
70
- Requires-Dist: coreason-identity (>=0.4.1,<0.5.0)
70
+ Requires-Dist: jsonschema (>=4.19.0,<5.0.0)
71
71
  Requires-Dist: loguru (>=0.7.2,<0.8.0)
72
72
  Requires-Dist: pydantic (>=2.12.5,<3.0.0)
73
73
  Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
@@ -87,31 +87,25 @@ The definitive source of truth for CoReason-AI Asset definitions. "The Blueprint
87
87
 
88
88
  ## Overview
89
89
 
90
- `coreason-manifest` serves as the **Shared Kernel** for the Coreason ecosystem. It contains the canonical Pydantic definitions, schemas, and data structures for Agents, Workflows (Recipes), and Auditing.
90
+ `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).
91
91
 
92
92
  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.
93
93
 
94
+ ### Standards Clarification
95
+ *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.*
96
+
94
97
  ## Features
95
98
 
96
- * **Open Agent Specification (OAS):** Strict Pydantic models for Agent definitions (`AgentDefinition`).
97
- * **Strict Typing:** Enforces type safety and immutable structures for critical interfaces.
98
- * **Enhanced Serialization:** Includes `CoReasonBaseModel` to ensure consistent JSON serialization of complex types like `UUID` and `datetime`.
99
- * **Event Protocol:** Defines the `GraphEvent` and `CloudEvent` structures for real-time communication.
100
- * **Simulation Schemas:** Provides standard models for `SimulationScenario`, `AdversaryProfile`, and `SimulationTrace`.
101
- * **Audit & Compliance:** Defines the `AuditLog` structure for tamper-evident record keeping.
102
- * **Ergonomic Factory Methods:** Simplified construction of `ChatMessage` and `GenAIOperation`.
103
- * **Token Arithmetic:** Support for `+` and `+=` operators on `GenAITokenUsage`.
104
- * **Flexible Tooling:** `ToolCallRequestPart` accepts JSON strings with automatic parsing.
105
- * **Enhanced Tracing:** `ReasoningTrace` includes flexible metadata for execution state.
99
+ * **Coreason Agent Manifest (CAM):** Strict Pydantic models for Agent definitions (`AgentDefinition`) and Recipes (`Recipe`).
100
+ * **Strict Typing:** Enforces type safety for critical interfaces.
101
+ * **Governance & Policy:** Enforce organizational rules (domains, risk levels) on agents via `GovernanceConfig`.
102
+ * **Ergonomic Factory Methods:** Simplified construction of manifests.
103
+ * **Flexible Tooling:** Support for external tool definitions (`ToolDefinition`) and risk levels (`ToolRiskLevel`).
104
+ * **Topology Visualization:** Workflows are defined as graph topologies (`Workflow`).
106
105
 
107
106
  ## Serialization & Base Model
108
107
 
109
- All core definitions (`AgentDefinition`, `RecipeManifest`, `GraphTopology`, `AuditLog`) inherit from `CoReasonBaseModel`. This provides a consistent interface for serialization, solving common Pydantic v2 issues with `UUID` and `datetime`.
110
-
111
- * Use `.dump()` to get a JSON-compatible dictionary (where UUIDs/datetimes are strings).
112
- * Use `.to_json()` to get a JSON string.
113
-
114
- For a detailed rationale, see [docs/coreason_base_model_rationale.md](docs/coreason_base_model_rationale.md).
108
+ Core definitions (e.g., `Manifest`, `Workflow`, `AgentDefinition`) inherit from Pydantic's `BaseModel`. Shared configuration models like `GovernanceConfig` inherit from `CoReasonBaseModel` for enhanced serialization capabilities.
115
109
 
116
110
  ## Installation
117
111
 
@@ -124,75 +118,57 @@ pip install coreason-manifest
124
118
  This library is used to define and validate Agent configurations programmatically.
125
119
 
126
120
  ```python
127
- import uuid
128
- from datetime import datetime, timezone
129
- from coreason_manifest.definitions.agent import (
130
- AgentDefinition,
131
- AgentMetadata,
132
- AgentInterface,
133
- AgentRuntimeConfig,
134
- ModelConfig,
135
- AgentDependencies,
136
- ToolRequirement,
137
- ToolRiskLevel,
138
- PolicyConfig,
139
- ObservabilityConfig,
140
- TraceLevel
121
+ from coreason_manifest import (
122
+ Recipe,
123
+ ManifestMetadata,
124
+ AgentStep,
125
+ Workflow,
126
+ InterfaceDefinition,
127
+ StateDefinition,
128
+ PolicyDefinition
141
129
  )
142
130
 
143
131
  # 1. Define Metadata
144
- metadata = AgentMetadata(
145
- id=uuid.uuid4(),
146
- version="1.0.0", # Strict SemVer
132
+ metadata = ManifestMetadata(
147
133
  name="Research Agent",
148
- author="Coreason AI",
149
- created_at=datetime.now(timezone.utc)
134
+ version="1.0.0"
135
+ )
136
+
137
+ # 2. Define Workflow
138
+ workflow = Workflow(
139
+ start="step1",
140
+ steps={
141
+ "step1": AgentStep(
142
+ id="step1",
143
+ agent="gpt-4-researcher",
144
+ next="step2"
145
+ ),
146
+ # ... define other steps
147
+ }
150
148
  )
151
149
 
152
- # 2. Instantiate Agent
153
- agent = AgentDefinition(
150
+ # 3. Instantiate Manifest
151
+ manifest = Recipe(
152
+ apiVersion="coreason.ai/v2",
153
+ kind="Recipe",
154
154
  metadata=metadata,
155
- interface=AgentInterface(
155
+ interface=InterfaceDefinition(
156
156
  inputs={"topic": {"type": "string"}},
157
157
  outputs={"summary": {"type": "string"}}
158
158
  ),
159
- config=AgentRuntimeConfig(
160
- model_config=ModelConfig(
161
- model="gpt-4",
162
- temperature=0.0,
163
- system_prompt="You are a helpful assistant."
164
- )
165
- ),
166
- dependencies=AgentDependencies(
167
- tools=[
168
- ToolRequirement(
169
- uri="mcp://search-service/google",
170
- hash="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", # Valid SHA256
171
- scopes=["search:read"],
172
- risk_level=ToolRiskLevel.STANDARD
173
- )
174
- ],
175
- libraries=("pandas==2.0.0",)
176
- ),
177
- policy=PolicyConfig(
178
- budget_caps={"total_cost": 5.0}
179
- ),
180
- observability=ObservabilityConfig(
181
- trace_level=TraceLevel.FULL,
182
- retention_policy="90_days"
183
- ),
184
- # Mandatory Integrity Hash
185
- integrity_hash="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
159
+ state=StateDefinition(),
160
+ policy=PolicyDefinition(max_retries=3),
161
+ workflow=workflow
186
162
  )
187
163
 
188
- print(f"Agent '{agent.metadata.name}' definition created and validated.")
164
+ print(f"Manifest '{manifest.metadata.name}' created successfully.")
189
165
  ```
190
166
 
191
167
  For full details, see the [Usage Documentation](docs/usage.md).
192
168
 
193
169
  ## Documentation
194
170
 
195
- * [Frontend Integration](docs/frontend_integration.md): Communicating with the Coreason Engine.
196
- * [Simulation Architecture](docs/simulation_architecture.md): Details on ATIF compatibility and GAIA scenarios.
197
- * [Audit & Compliance](docs/audit_compliance.md): Details on EU AI Act compliance, Chain of Custody, and Integrity Hashing.
171
+ * [Usage Guide](docs/usage.md): How to load and create manifests.
172
+ * [Governance & Policy Enforcement](docs/governance_policy_enforcement.md): Validating agents against organizational rules.
173
+ * [Coreason Agent Manifest (CAM)](docs/cap/specification.md): The Canonical YAML Authoring Format.
198
174
 
@@ -0,0 +1,20 @@
1
+ coreason_manifest/__init__.py,sha256=qy8VLZO7M4S_PWl4PB7PIztcPd_JgvKUW64S3oty0UY,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=Y9j1W0rFAh5lMAJbgMnqnyu9XmvgYdW895N5NeLvee0,461
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.13.0.dist-info/METADATA,sha256=D4Hltcoz_4efVfP6PO3zG3H5gewSn5seUbOqjmCx54c,8228
17
+ coreason_manifest-0.13.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
18
+ coreason_manifest-0.13.0.dist-info/licenses/LICENSE,sha256=3tYb7ZQe7sVXcbNmX22fDESFjOSIlCZodUGpZMkuSlk,3063
19
+ coreason_manifest-0.13.0.dist-info/licenses/NOTICE,sha256=tqzUyP9VTCGxoHLgBI0AC1i0G7m_PSyESFL8Jwuw0dA,610
20
+ coreason_manifest-0.13.0.dist-info/RECORD,,
@@ -1,60 +0,0 @@
1
- # Copyright (c) 2025 CoReason, Inc.
2
- #
3
- # This software is proprietary and dual-licensed.
4
- # Licensed under the Prosperity Public License 3.0 (the "License").
5
- # A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
6
- # For details, see the LICENSE file.
7
- # Commercial use beyond a 30-day trial requires a separate license.
8
- #
9
- # Source Code: https://github.com/CoReason-AI/coreason-manifest
10
-
11
- from .agent import AgentDefinition, AgentRuntimeConfig, Persona
12
- from .events import (
13
- ArtifactGenerated,
14
- ArtifactGeneratedPayload,
15
- CouncilVote,
16
- CouncilVotePayload,
17
- EdgeTraversed,
18
- EdgeTraversedPayload,
19
- GraphEvent,
20
- NodeCompleted,
21
- NodeCompletedPayload,
22
- NodeInit,
23
- # Export Aliases too
24
- NodeInitPayload,
25
- NodeRestored,
26
- NodeSkipped,
27
- NodeSkippedPayload,
28
- NodeStarted,
29
- NodeStartedPayload,
30
- NodeStream,
31
- NodeStreamPayload,
32
- WorkflowError,
33
- WorkflowErrorPayload,
34
- )
35
-
36
- __all__ = [
37
- "AgentRuntimeConfig",
38
- "AgentDefinition",
39
- "Persona",
40
- "GraphEvent",
41
- "NodeInit",
42
- "NodeStarted",
43
- "NodeCompleted",
44
- "NodeRestored",
45
- "NodeSkipped",
46
- "NodeStream",
47
- "ArtifactGenerated",
48
- "EdgeTraversed",
49
- "CouncilVote",
50
- "WorkflowError",
51
- "NodeInitPayload",
52
- "NodeStartedPayload",
53
- "NodeCompletedPayload",
54
- "NodeSkippedPayload",
55
- "NodeStreamPayload",
56
- "EdgeTraversedPayload",
57
- "ArtifactGeneratedPayload",
58
- "CouncilVotePayload",
59
- "WorkflowErrorPayload",
60
- ]
@@ -1,370 +0,0 @@
1
- # Copyright (c) 2025 CoReason, Inc.
2
- #
3
- # This software is proprietary and dual-licensed.
4
- # Licensed under the Prosperity Public License 3.0 (the "License").
5
- # A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
6
- # For details, see the LICENSE file.
7
- # Commercial use beyond a 30-day trial requires a separate license.
8
- #
9
- # Source Code: https://github.com/CoReason-AI/coreason-manifest
10
-
11
- """Pydantic models for the Coreason Manifest system.
12
-
13
- These models define the structure and validation rules for the Agent Manifest
14
- (OAS). They represent the source of truth for Agent definitions.
15
- """
16
-
17
- from __future__ import annotations
18
-
19
- from datetime import datetime
20
- from enum import Enum
21
- from types import MappingProxyType
22
- from typing import Any, Dict, List, Literal, Mapping, Optional, Tuple, Union
23
- from uuid import UUID
24
-
25
- from pydantic import (
26
- AfterValidator,
27
- AnyUrl,
28
- ConfigDict,
29
- Field,
30
- PlainSerializer,
31
- field_validator,
32
- model_validator,
33
- )
34
- from typing_extensions import Annotated
35
-
36
- from coreason_manifest.definitions.base import CoReasonBaseModel
37
- from coreason_manifest.definitions.topology import Edge, Node, validate_edge_integrity
38
-
39
- # SemVer Regex pattern (simplified for standard SemVer)
40
- # Modified to accept optional 'v' or 'V' prefix (multiple allowed) for input normalization
41
- SEMVER_REGEX = (
42
- r"^[vV]*(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)"
43
- 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-]*))*))?"
44
- r"(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
45
- )
46
-
47
-
48
- def normalize_version(v: str) -> str:
49
- """Normalize version string by recursively stripping 'v' or 'V' prefix.
50
-
51
- Args:
52
- v: The version string to normalize.
53
-
54
- Returns:
55
- The normalized version string without 'v' prefix.
56
- """
57
- while v.lower().startswith("v"):
58
- v = v[1:]
59
- return v
60
-
61
-
62
- # Annotated type that validates SemVer regex (allowing multiple v) then normalizes to strict SemVer (no v)
63
- VersionStr = Annotated[
64
- str,
65
- Field(pattern=SEMVER_REGEX),
66
- AfterValidator(normalize_version),
67
- ]
68
-
69
- # Reusable immutable dictionary type
70
- ImmutableDict = Annotated[
71
- Mapping[str, Any],
72
- AfterValidator(lambda x: MappingProxyType(x)),
73
- PlainSerializer(lambda x: dict(x), return_type=Dict[str, Any]),
74
- ]
75
-
76
-
77
- # Strict URI type that serializes to string
78
- StrictUri = Annotated[
79
- AnyUrl,
80
- PlainSerializer(lambda x: str(x), return_type=str),
81
- ]
82
-
83
-
84
- class AgentMetadata(CoReasonBaseModel):
85
- """Metadata for the Agent.
86
-
87
- Attributes:
88
- id: Unique Identifier for the Agent (UUID).
89
- version: Semantic Version of the Agent.
90
- name: Name of the Agent.
91
- author: Author of the Agent.
92
- created_at: Creation timestamp (ISO 8601).
93
- """
94
-
95
- model_config = ConfigDict(extra="forbid", frozen=True)
96
-
97
- id: UUID = Field(..., description="Unique Identifier for the Agent (UUID).")
98
- version: VersionStr = Field(..., description="Semantic Version of the Agent.")
99
- name: str = Field(..., min_length=1, description="Name of the Agent.")
100
- author: str = Field(..., min_length=1, description="Author of the Agent.")
101
- created_at: datetime = Field(..., description="Creation timestamp (ISO 8601).")
102
- requires_auth: bool = Field(default=False, description="Whether the agent requires user authentication.")
103
-
104
-
105
- class Persona(CoReasonBaseModel):
106
- """Definition of an Agent Persona.
107
-
108
- Attributes:
109
- name: Name of the persona.
110
- description: Description of the persona.
111
- directives: List of specific instructions or directives.
112
- """
113
-
114
- model_config = ConfigDict(extra="forbid", frozen=True)
115
-
116
- name: str = Field(..., description="Name of the persona.")
117
- description: str = Field(..., description="Description of the persona.")
118
- directives: List[str] = Field(..., description="List of specific instructions or directives.")
119
-
120
-
121
- class AgentInterface(CoReasonBaseModel):
122
- """Interface definition for the Agent.
123
-
124
- Attributes:
125
- inputs: Typed arguments the agent accepts (JSON Schema).
126
- outputs: Typed structure of the result.
127
- """
128
-
129
- model_config = ConfigDict(extra="forbid", frozen=True)
130
-
131
- inputs: ImmutableDict = Field(..., description="Typed arguments the agent accepts (JSON Schema).")
132
- outputs: ImmutableDict = Field(..., description="Typed structure of the result.")
133
- injected_params: List[str] = Field(default_factory=list, description="List of parameters injected by the system.")
134
-
135
-
136
- class ModelConfig(CoReasonBaseModel):
137
- """LLM Configuration parameters.
138
-
139
- Attributes:
140
- model: The LLM model identifier.
141
- temperature: Temperature for generation.
142
- system_prompt: The default system prompt/persona for the agent.
143
- persona: The full persona definition (name, description, directives).
144
- """
145
-
146
- model_config = ConfigDict(extra="forbid", frozen=True)
147
-
148
- model: str = Field(..., description="The LLM model identifier.")
149
- temperature: float = Field(..., ge=0.0, le=2.0, description="Temperature for generation.")
150
- system_prompt: Optional[str] = Field(None, description="The default system prompt/persona for the agent.")
151
- persona: Optional[Persona] = Field(None, description="The full persona definition (name, description, directives).")
152
-
153
-
154
- class AgentRuntimeConfig(CoReasonBaseModel):
155
- """Configuration of the Agent execution.
156
-
157
- Attributes:
158
- nodes: A collection of execution units (Agents, Tools, Logic).
159
- edges: Directed connections defining control flow.
160
- entry_point: The ID of the starting node.
161
- llm_config: Specific LLM parameters.
162
- """
163
-
164
- model_config = ConfigDict(extra="forbid", frozen=True)
165
-
166
- nodes: List[Node] = Field(default_factory=list, description="A collection of execution units.")
167
- edges: List[Edge] = Field(default_factory=list, description="Directed connections defining control flow.")
168
- entry_point: Optional[str] = Field(None, description="The ID of the starting node.")
169
- llm_config: ModelConfig = Field(..., alias="model_config", description="Specific LLM parameters.")
170
- system_prompt: Optional[str] = Field(None, description="The global system prompt/instruction for the agent.")
171
-
172
- @model_validator(mode="after")
173
- def validate_topology_or_atomic(self) -> AgentRuntimeConfig:
174
- """Ensure valid configuration: either a Graph or an Atomic Agent."""
175
- has_nodes = len(self.nodes) > 0
176
- has_entry = self.entry_point is not None
177
-
178
- if has_nodes:
179
- if not has_entry:
180
- raise ValueError("Graph execution requires an 'entry_point'.")
181
- else:
182
- # Atomic Agent: Must have a system prompt (either global or in model_config)
183
- has_global_prompt = self.system_prompt is not None
184
- has_model_prompt = self.llm_config.system_prompt is not None
185
-
186
- if not (has_global_prompt or has_model_prompt):
187
- raise ValueError("Atomic Agents require a system_prompt (global or in model_config).")
188
-
189
- return self
190
-
191
- @model_validator(mode="after")
192
- def validate_topology_integrity(self) -> AgentRuntimeConfig:
193
- """Ensure that edges connect existing nodes."""
194
- validate_edge_integrity(self.nodes, self.edges)
195
- return self
196
-
197
- @field_validator("nodes")
198
- @classmethod
199
- def validate_unique_node_ids(cls, v: List[Node]) -> List[Node]:
200
- """Ensure all node IDs are unique.
201
-
202
- Args:
203
- v: The list of nodes to validate.
204
-
205
- Returns:
206
- The validated list of nodes.
207
-
208
- Raises:
209
- ValueError: If duplicate node IDs are found.
210
- """
211
- ids = [node.id for node in v]
212
- if len(ids) != len(set(ids)):
213
- # Find duplicates
214
- seen = set()
215
- dupes = set()
216
- for x in ids:
217
- if x in seen:
218
- dupes.add(x)
219
- seen.add(x)
220
- raise ValueError(f"Duplicate node IDs found: {', '.join(dupes)}")
221
- return v
222
-
223
-
224
- class ToolRiskLevel(str, Enum):
225
- """Risk level for the tool."""
226
-
227
- SAFE = "safe"
228
- STANDARD = "standard"
229
- CRITICAL = "critical"
230
-
231
-
232
- class ToolRequirement(CoReasonBaseModel):
233
- """Requirement for an MCP tool.
234
-
235
- Attributes:
236
- uri: The MCP endpoint URI.
237
- hash: Integrity check for the tool definition (SHA256).
238
- scopes: List of permissions required.
239
- risk_level: The risk level of the tool.
240
- """
241
-
242
- model_config = ConfigDict(extra="forbid", frozen=True)
243
-
244
- uri: StrictUri = Field(..., description="The MCP endpoint URI.")
245
- hash: str = Field(
246
- ..., pattern=r"^[a-fA-F0-9]{64}$", description="Integrity check for the tool definition (SHA256)."
247
- )
248
- scopes: List[str] = Field(..., description="List of permissions required.")
249
- risk_level: ToolRiskLevel = Field(..., description="The risk level of the tool.")
250
-
251
-
252
- class InlineToolDefinition(CoReasonBaseModel):
253
- """Definition of an inline tool.
254
-
255
- Attributes:
256
- name: Name of the tool.
257
- description: Description of the tool.
258
- parameters: JSON Schema of parameters.
259
- type: The type of the tool (must be 'function').
260
- """
261
-
262
- model_config = ConfigDict(extra="forbid", frozen=True)
263
-
264
- name: str = Field(..., description="Name of the tool.")
265
- description: str = Field(..., description="Description of the tool.")
266
- parameters: Dict[str, Any] = Field(..., description="JSON Schema of parameters.")
267
- type: Literal["function"] = Field("function", description="The type of the tool (must be 'function').")
268
-
269
-
270
- class AgentDependencies(CoReasonBaseModel):
271
- """External dependencies for the Agent.
272
-
273
- Attributes:
274
- tools: List of MCP tool requirements.
275
- libraries: List of Python packages required (if code execution is allowed).
276
- """
277
-
278
- model_config = ConfigDict(extra="forbid", frozen=True)
279
-
280
- tools: List[Union[ToolRequirement, InlineToolDefinition]] = Field(
281
- default_factory=list, description="List of MCP tool requirements."
282
- )
283
- libraries: Tuple[str, ...] = Field(
284
- default_factory=tuple, description="List of Python packages required (if code execution is allowed)."
285
- )
286
-
287
-
288
- class PolicyConfig(CoReasonBaseModel):
289
- """Governance policy configuration.
290
-
291
- Attributes:
292
- budget_caps: Dictionary defining budget limits (e.g., {"total_cost": 10.0, "total_tokens": 1000}).
293
- human_in_the_loop: List of Node IDs that require human approval.
294
- allowed_domains: List of allowed domains for external access.
295
- """
296
-
297
- model_config = ConfigDict(extra="forbid", frozen=True)
298
-
299
- budget_caps: Dict[str, float] = Field(default_factory=dict, description="Budget limits.")
300
- human_in_the_loop: List[str] = Field(default_factory=list, description="Node IDs requiring human approval.")
301
- allowed_domains: List[str] = Field(default_factory=list, description="Allowed domains for external access.")
302
-
303
-
304
- class TraceLevel(str, Enum):
305
- """Level of tracing detail."""
306
-
307
- FULL = "full"
308
- METADATA_ONLY = "metadata_only"
309
- NONE = "none"
310
-
311
-
312
- class ObservabilityConfig(CoReasonBaseModel):
313
- """Observability configuration.
314
-
315
- Attributes:
316
- trace_level: Level of tracing detail.
317
- retention_policy: Retention policy identifier (e.g., '30_days').
318
- encryption_key_id: Optional ID of the key used for log encryption.
319
- """
320
-
321
- model_config = ConfigDict(extra="forbid", frozen=True)
322
-
323
- trace_level: TraceLevel = Field(default=TraceLevel.FULL, description="Level of tracing detail.")
324
- retention_policy: str = Field(default="30_days", description="Retention policy identifier.")
325
- encryption_key_id: Optional[str] = Field(None, description="Optional ID of the key used for log encryption.")
326
-
327
-
328
- class AgentDefinition(CoReasonBaseModel):
329
- """The Root Object for the CoReason Agent Manifest.
330
-
331
- Attributes:
332
- metadata: Metadata for the Agent.
333
- interface: Interface definition for the Agent.
334
- config: Configuration of the Agent execution.
335
- dependencies: External dependencies for the Agent.
336
- integrity_hash: SHA256 hash of the source code.
337
- """
338
-
339
- model_config = ConfigDict(
340
- extra="forbid",
341
- frozen=True,
342
- title="CoReason Agent Manifest",
343
- json_schema_extra={
344
- "$id": "https://coreason.ai/schemas/agent.schema.json",
345
- "description": "The definitive source of truth for CoReason Agent definitions.",
346
- },
347
- )
348
-
349
- metadata: AgentMetadata
350
- interface: AgentInterface
351
- config: AgentRuntimeConfig
352
- dependencies: AgentDependencies
353
- policy: Optional[PolicyConfig] = Field(None, description="Governance policy configuration.")
354
- observability: Optional[ObservabilityConfig] = Field(None, description="Observability configuration.")
355
- custom_metadata: Optional[Dict[str, Any]] = Field(
356
- None, description="Container for arbitrary metadata extensions without breaking validation."
357
- )
358
- integrity_hash: str = Field(
359
- ...,
360
- pattern=r"^[a-fA-F0-9]{64}$",
361
- description="SHA256 hash of the source code.",
362
- )
363
-
364
- @model_validator(mode="after")
365
- def validate_auth_requirements(self) -> AgentDefinition:
366
- """Validate that agents requiring auth have user_context injected."""
367
- if self.metadata.requires_auth:
368
- if "user_context" not in self.interface.injected_params:
369
- raise ValueError("Agent requires authentication but 'user_context' is not an injected parameter.")
370
- return self