coreason-manifest 0.7.0__py3-none-any.whl → 0.9.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 +2 -2
- coreason_manifest/definitions/__init__.py +49 -0
- coreason_manifest/definitions/agent.py +93 -32
- coreason_manifest/definitions/audit.py +118 -3
- coreason_manifest/definitions/events.py +392 -0
- coreason_manifest/definitions/message.py +126 -0
- coreason_manifest/definitions/simulation.py +39 -8
- coreason_manifest/definitions/topology.py +119 -4
- coreason_manifest/recipes.py +43 -5
- coreason_manifest/schemas/agent.schema.json +652 -26
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.9.0.dist-info}/METADATA +1 -1
- coreason_manifest-0.9.0.dist-info/RECORD +18 -0
- coreason_manifest-0.7.0.dist-info/RECORD +0 -16
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.9.0.dist-info}/WHEEL +0 -0
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.9.0.dist-info}/licenses/LICENSE +0 -0
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.9.0.dist-info}/licenses/NOTICE +0 -0
coreason_manifest/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from .definitions.agent import AgentDefinition
|
|
2
2
|
from .definitions.audit import AuditLog
|
|
3
|
-
from .definitions.simulation import SimulationScenario,
|
|
3
|
+
from .definitions.simulation import SimulationScenario, SimulationStep, SimulationTrace
|
|
4
4
|
from .definitions.topology import Edge, Node, Topology
|
|
5
5
|
from .recipes import RecipeManifest
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ __all__ = [
|
|
|
11
11
|
"Edge",
|
|
12
12
|
"SimulationScenario",
|
|
13
13
|
"SimulationTrace",
|
|
14
|
-
"
|
|
14
|
+
"SimulationStep",
|
|
15
15
|
"AuditLog",
|
|
16
16
|
"RecipeManifest",
|
|
17
17
|
]
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
]
|
|
@@ -8,6 +8,7 @@ These models define the structure and validation rules for the Agent Manifest
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
from datetime import datetime
|
|
11
|
+
from enum import Enum
|
|
11
12
|
from types import MappingProxyType
|
|
12
13
|
from typing import Any, Dict, List, Mapping, Optional, Tuple
|
|
13
14
|
from uuid import UUID
|
|
@@ -24,6 +25,8 @@ from pydantic import (
|
|
|
24
25
|
)
|
|
25
26
|
from typing_extensions import Annotated
|
|
26
27
|
|
|
28
|
+
from coreason_manifest.definitions.topology import Edge, Node
|
|
29
|
+
|
|
27
30
|
# SemVer Regex pattern (simplified for standard SemVer)
|
|
28
31
|
# Modified to accept optional 'v' or 'V' prefix (multiple allowed) for input normalization
|
|
29
32
|
SEMVER_REGEX = (
|
|
@@ -105,20 +108,6 @@ class AgentInterface(BaseModel):
|
|
|
105
108
|
injected_params: List[str] = Field(default_factory=list, description="List of parameters injected by the system.")
|
|
106
109
|
|
|
107
110
|
|
|
108
|
-
class Step(BaseModel):
|
|
109
|
-
"""A single step in the execution graph.
|
|
110
|
-
|
|
111
|
-
Attributes:
|
|
112
|
-
id: Unique identifier for the step.
|
|
113
|
-
description: Description of the step.
|
|
114
|
-
"""
|
|
115
|
-
|
|
116
|
-
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
117
|
-
|
|
118
|
-
id: str = Field(..., min_length=1, description="Unique identifier for the step.")
|
|
119
|
-
description: Optional[str] = Field(None, description="Description of the step.")
|
|
120
|
-
|
|
121
|
-
|
|
122
111
|
class ModelConfig(BaseModel):
|
|
123
112
|
"""LLM Configuration parameters.
|
|
124
113
|
|
|
@@ -133,34 +122,38 @@ class ModelConfig(BaseModel):
|
|
|
133
122
|
temperature: float = Field(..., ge=0.0, le=2.0, description="Temperature for generation.")
|
|
134
123
|
|
|
135
124
|
|
|
136
|
-
class
|
|
137
|
-
"""
|
|
125
|
+
class AgentRuntimeConfig(BaseModel):
|
|
126
|
+
"""Configuration of the Agent execution.
|
|
138
127
|
|
|
139
128
|
Attributes:
|
|
140
|
-
|
|
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.
|
|
141
132
|
llm_config: Specific LLM parameters.
|
|
142
133
|
"""
|
|
143
134
|
|
|
144
135
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
145
136
|
|
|
146
|
-
|
|
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.")
|
|
147
140
|
llm_config: ModelConfig = Field(..., alias="model_config", description="Specific LLM parameters.")
|
|
148
141
|
|
|
149
|
-
@field_validator("
|
|
142
|
+
@field_validator("nodes")
|
|
150
143
|
@classmethod
|
|
151
|
-
def
|
|
152
|
-
"""Ensure all
|
|
144
|
+
def validate_unique_node_ids(cls, v: List[Node]) -> List[Node]:
|
|
145
|
+
"""Ensure all node IDs are unique.
|
|
153
146
|
|
|
154
147
|
Args:
|
|
155
|
-
v: The
|
|
148
|
+
v: The list of nodes to validate.
|
|
156
149
|
|
|
157
150
|
Returns:
|
|
158
|
-
The validated
|
|
151
|
+
The validated list of nodes.
|
|
159
152
|
|
|
160
153
|
Raises:
|
|
161
|
-
ValueError: If duplicate
|
|
154
|
+
ValueError: If duplicate node IDs are found.
|
|
162
155
|
"""
|
|
163
|
-
ids = [
|
|
156
|
+
ids = [node.id for node in v]
|
|
164
157
|
if len(ids) != len(set(ids)):
|
|
165
158
|
# Find duplicates
|
|
166
159
|
seen = set()
|
|
@@ -169,35 +162,101 @@ class AgentTopology(BaseModel):
|
|
|
169
162
|
if x in seen:
|
|
170
163
|
dupes.add(x)
|
|
171
164
|
seen.add(x)
|
|
172
|
-
raise ValueError(f"Duplicate
|
|
165
|
+
raise ValueError(f"Duplicate node IDs found: {', '.join(dupes)}")
|
|
173
166
|
return v
|
|
174
167
|
|
|
175
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
|
+
|
|
176
197
|
class AgentDependencies(BaseModel):
|
|
177
198
|
"""External dependencies for the Agent.
|
|
178
199
|
|
|
179
200
|
Attributes:
|
|
180
|
-
tools: List of MCP
|
|
201
|
+
tools: List of MCP tool requirements.
|
|
181
202
|
libraries: List of Python packages required (if code execution is allowed).
|
|
182
203
|
"""
|
|
183
204
|
|
|
184
205
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
185
206
|
|
|
186
|
-
|
|
187
|
-
# Changed to List[StrictUri] to strictly enforce valid URI formatting and string serialization
|
|
188
|
-
tools: List[StrictUri] = Field(default_factory=list, description="List of MCP capability URIs required.")
|
|
207
|
+
tools: List[ToolRequirement] = Field(default_factory=list, description="List of MCP tool requirements.")
|
|
189
208
|
libraries: Tuple[str, ...] = Field(
|
|
190
209
|
default_factory=tuple, description="List of Python packages required (if code execution is allowed)."
|
|
191
210
|
)
|
|
192
211
|
|
|
193
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
|
+
|
|
194
253
|
class AgentDefinition(BaseModel):
|
|
195
254
|
"""The Root Object for the CoReason Agent Manifest.
|
|
196
255
|
|
|
197
256
|
Attributes:
|
|
198
257
|
metadata: Metadata for the Agent.
|
|
199
258
|
interface: Interface definition for the Agent.
|
|
200
|
-
|
|
259
|
+
config: Configuration of the Agent execution.
|
|
201
260
|
dependencies: External dependencies for the Agent.
|
|
202
261
|
integrity_hash: SHA256 hash of the source code.
|
|
203
262
|
"""
|
|
@@ -214,8 +273,10 @@ class AgentDefinition(BaseModel):
|
|
|
214
273
|
|
|
215
274
|
metadata: AgentMetadata
|
|
216
275
|
interface: AgentInterface
|
|
217
|
-
|
|
276
|
+
config: AgentRuntimeConfig
|
|
218
277
|
dependencies: AgentDependencies
|
|
278
|
+
policy: Optional[PolicyConfig] = Field(None, description="Governance policy configuration.")
|
|
279
|
+
observability: Optional[ObservabilityConfig] = Field(None, description="Observability configuration.")
|
|
219
280
|
integrity_hash: str = Field(
|
|
220
281
|
...,
|
|
221
282
|
pattern=r"^[a-fA-F0-9]{64}$",
|
|
@@ -1,7 +1,122 @@
|
|
|
1
|
-
|
|
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"
|
|
2
91
|
|
|
3
92
|
|
|
4
93
|
class AuditLog(BaseModel):
|
|
5
|
-
"""
|
|
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
|
+
|
|
6
118
|
|
|
7
|
-
|
|
119
|
+
# --- Backward Compatibility ---
|
|
120
|
+
# Adapters or Aliases
|
|
121
|
+
CognitiveStep = GenAIOperation
|
|
122
|
+
TokenUsage = GenAITokenUsage
|