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.
- coreason_manifest/__init__.py +35 -82
- coreason_manifest/{definitions/base.py → common.py} +18 -1
- coreason_manifest/governance.py +83 -0
- coreason_manifest/schemas/coreason-v2.schema.json +462 -0
- coreason_manifest/utils/logger.py +0 -45
- coreason_manifest/v2/__init__.py +1 -0
- coreason_manifest/v2/governance.py +144 -0
- coreason_manifest/v2/io.py +132 -0
- coreason_manifest/v2/resolver.py +67 -0
- coreason_manifest/v2/spec/__init__.py +1 -0
- coreason_manifest/v2/spec/contracts.py +34 -0
- coreason_manifest/v2/spec/definitions.py +196 -0
- coreason_manifest/v2/validator.py +48 -0
- {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/METADATA +48 -72
- coreason_manifest-0.13.0.dist-info/RECORD +20 -0
- coreason_manifest/definitions/__init__.py +0 -60
- coreason_manifest/definitions/agent.py +0 -370
- coreason_manifest/definitions/audit.py +0 -181
- coreason_manifest/definitions/events.py +0 -423
- coreason_manifest/definitions/message.py +0 -188
- coreason_manifest/definitions/simulation.py +0 -79
- coreason_manifest/definitions/simulation_config.py +0 -46
- coreason_manifest/definitions/topology.py +0 -341
- coreason_manifest/recipes.py +0 -84
- coreason_manifest/schemas/agent.schema.json +0 -1051
- coreason_manifest/schemas/recipe.schema.json +0 -813
- coreason_manifest/v1/__init__.py +0 -15
- coreason_manifest-0.10.0.dist-info/RECORD +0 -22
- {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/WHEEL +0 -0
- {coreason_manifest-0.10.0.dist-info → coreason_manifest-0.13.0.dist-info}/licenses/LICENSE +0 -0
- {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.
|
|
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:
|
|
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
|
|
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
|
-
* **
|
|
97
|
-
* **Strict Typing:** Enforces type safety
|
|
98
|
-
* **
|
|
99
|
-
* **
|
|
100
|
-
* **
|
|
101
|
-
* **
|
|
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
|
-
|
|
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
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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 =
|
|
145
|
-
id=uuid.uuid4(),
|
|
146
|
-
version="1.0.0", # Strict SemVer
|
|
132
|
+
metadata = ManifestMetadata(
|
|
147
133
|
name="Research Agent",
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
#
|
|
153
|
-
|
|
150
|
+
# 3. Instantiate Manifest
|
|
151
|
+
manifest = Recipe(
|
|
152
|
+
apiVersion="coreason.ai/v2",
|
|
153
|
+
kind="Recipe",
|
|
154
154
|
metadata=metadata,
|
|
155
|
-
interface=
|
|
155
|
+
interface=InterfaceDefinition(
|
|
156
156
|
inputs={"topic": {"type": "string"}},
|
|
157
157
|
outputs={"summary": {"type": "string"}}
|
|
158
158
|
),
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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"
|
|
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
|
-
* [
|
|
196
|
-
* [
|
|
197
|
-
* [
|
|
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
|