coreason-manifest 0.9.0__py3-none-any.whl → 0.10.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.
@@ -1,17 +1,98 @@
1
- from .definitions.agent import AgentDefinition
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 .definitions.agent import AgentDefinition, Persona
2
12
  from .definitions.audit import AuditLog
3
- from .definitions.simulation import SimulationScenario, SimulationStep, SimulationTrace
4
- from .definitions.topology import Edge, Node, Topology
13
+ from .definitions.events import (
14
+ ArtifactGenerated,
15
+ CloudEvent,
16
+ CouncilVote,
17
+ EdgeTraversed,
18
+ GraphEvent,
19
+ GraphEventArtifactGenerated,
20
+ GraphEventCouncilVote,
21
+ GraphEventEdgeActive,
22
+ GraphEventError,
23
+ GraphEventNodeDone,
24
+ GraphEventNodeInit,
25
+ GraphEventNodeRestored,
26
+ GraphEventNodeSkipped,
27
+ GraphEventNodeStart,
28
+ GraphEventNodeStream,
29
+ NodeCompleted,
30
+ NodeInit,
31
+ NodeRestored,
32
+ NodeSkipped,
33
+ NodeStarted,
34
+ NodeStream,
35
+ WorkflowError,
36
+ migrate_graph_event_to_cloud_event,
37
+ )
38
+ from .definitions.simulation import (
39
+ SimulationMetrics,
40
+ SimulationScenario,
41
+ SimulationStep,
42
+ SimulationTrace,
43
+ StepType,
44
+ )
45
+ from .definitions.simulation_config import AdversaryProfile, ChaosConfig, SimulationRequest
46
+ from .definitions.topology import (
47
+ AgentNode,
48
+ Edge,
49
+ GraphTopology,
50
+ Node,
51
+ StateDefinition,
52
+ Topology,
53
+ )
5
54
  from .recipes import RecipeManifest
6
55
 
7
56
  __all__ = [
8
57
  "AgentDefinition",
58
+ "Persona",
9
59
  "Topology",
60
+ "GraphTopology",
10
61
  "Node",
62
+ "AgentNode",
11
63
  "Edge",
64
+ "StateDefinition",
65
+ "GraphEvent",
66
+ "CloudEvent",
67
+ "GraphEventNodeInit",
68
+ "GraphEventNodeStart",
69
+ "GraphEventNodeDone",
70
+ "GraphEventNodeStream",
71
+ "GraphEventNodeSkipped",
72
+ "GraphEventNodeRestored",
73
+ "GraphEventEdgeActive",
74
+ "GraphEventCouncilVote",
75
+ "GraphEventError",
76
+ "GraphEventArtifactGenerated",
77
+ "NodeInit",
78
+ "NodeStarted",
79
+ "NodeCompleted",
80
+ "NodeStream",
81
+ "NodeSkipped",
82
+ "NodeRestored",
83
+ "WorkflowError",
84
+ "CouncilVote",
85
+ "ArtifactGenerated",
86
+ "EdgeTraversed",
87
+ "migrate_graph_event_to_cloud_event",
12
88
  "SimulationScenario",
13
89
  "SimulationTrace",
14
90
  "SimulationStep",
91
+ "SimulationMetrics",
92
+ "StepType",
93
+ "AdversaryProfile",
94
+ "ChaosConfig",
95
+ "SimulationRequest",
15
96
  "AuditLog",
16
97
  "RecipeManifest",
17
98
  ]
@@ -1,4 +1,14 @@
1
- from .agent import AgentDefinition, AgentRuntimeConfig
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
2
12
  from .events import (
3
13
  ArtifactGenerated,
4
14
  ArtifactGeneratedPayload,
@@ -26,6 +36,7 @@ from .events import (
26
36
  __all__ = [
27
37
  "AgentRuntimeConfig",
28
38
  "AgentDefinition",
39
+ "Persona",
29
40
  "GraphEvent",
30
41
  "NodeInit",
31
42
  "NodeStarted",
@@ -1,4 +1,13 @@
1
- # Prosperity-3.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
+
2
11
  """Pydantic models for the Coreason Manifest system.
3
12
 
4
13
  These models define the structure and validation rules for the Agent Manifest
@@ -10,13 +19,12 @@ from __future__ import annotations
10
19
  from datetime import datetime
11
20
  from enum import Enum
12
21
  from types import MappingProxyType
13
- from typing import Any, Dict, List, Mapping, Optional, Tuple
22
+ from typing import Any, Dict, List, Literal, Mapping, Optional, Tuple, Union
14
23
  from uuid import UUID
15
24
 
16
25
  from pydantic import (
17
26
  AfterValidator,
18
27
  AnyUrl,
19
- BaseModel,
20
28
  ConfigDict,
21
29
  Field,
22
30
  PlainSerializer,
@@ -25,7 +33,8 @@ from pydantic import (
25
33
  )
26
34
  from typing_extensions import Annotated
27
35
 
28
- from coreason_manifest.definitions.topology import Edge, Node
36
+ from coreason_manifest.definitions.base import CoReasonBaseModel
37
+ from coreason_manifest.definitions.topology import Edge, Node, validate_edge_integrity
29
38
 
30
39
  # SemVer Regex pattern (simplified for standard SemVer)
31
40
  # Modified to accept optional 'v' or 'V' prefix (multiple allowed) for input normalization
@@ -72,7 +81,7 @@ StrictUri = Annotated[
72
81
  ]
73
82
 
74
83
 
75
- class AgentMetadata(BaseModel):
84
+ class AgentMetadata(CoReasonBaseModel):
76
85
  """Metadata for the Agent.
77
86
 
78
87
  Attributes:
@@ -93,7 +102,23 @@ class AgentMetadata(BaseModel):
93
102
  requires_auth: bool = Field(default=False, description="Whether the agent requires user authentication.")
94
103
 
95
104
 
96
- class AgentInterface(BaseModel):
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):
97
122
  """Interface definition for the Agent.
98
123
 
99
124
  Attributes:
@@ -108,21 +133,25 @@ class AgentInterface(BaseModel):
108
133
  injected_params: List[str] = Field(default_factory=list, description="List of parameters injected by the system.")
109
134
 
110
135
 
111
- class ModelConfig(BaseModel):
136
+ class ModelConfig(CoReasonBaseModel):
112
137
  """LLM Configuration parameters.
113
138
 
114
139
  Attributes:
115
140
  model: The LLM model identifier.
116
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).
117
144
  """
118
145
 
119
146
  model_config = ConfigDict(extra="forbid", frozen=True)
120
147
 
121
148
  model: str = Field(..., description="The LLM model identifier.")
122
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).")
123
152
 
124
153
 
125
- class AgentRuntimeConfig(BaseModel):
154
+ class AgentRuntimeConfig(CoReasonBaseModel):
126
155
  """Configuration of the Agent execution.
127
156
 
128
157
  Attributes:
@@ -134,10 +163,36 @@ class AgentRuntimeConfig(BaseModel):
134
163
 
135
164
  model_config = ConfigDict(extra="forbid", frozen=True)
136
165
 
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.")
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.")
140
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
141
196
 
142
197
  @field_validator("nodes")
143
198
  @classmethod
@@ -174,7 +229,7 @@ class ToolRiskLevel(str, Enum):
174
229
  CRITICAL = "critical"
175
230
 
176
231
 
177
- class ToolRequirement(BaseModel):
232
+ class ToolRequirement(CoReasonBaseModel):
178
233
  """Requirement for an MCP tool.
179
234
 
180
235
  Attributes:
@@ -194,7 +249,25 @@ class ToolRequirement(BaseModel):
194
249
  risk_level: ToolRiskLevel = Field(..., description="The risk level of the tool.")
195
250
 
196
251
 
197
- class AgentDependencies(BaseModel):
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):
198
271
  """External dependencies for the Agent.
199
272
 
200
273
  Attributes:
@@ -204,13 +277,15 @@ class AgentDependencies(BaseModel):
204
277
 
205
278
  model_config = ConfigDict(extra="forbid", frozen=True)
206
279
 
207
- tools: List[ToolRequirement] = Field(default_factory=list, description="List of MCP tool requirements.")
280
+ tools: List[Union[ToolRequirement, InlineToolDefinition]] = Field(
281
+ default_factory=list, description="List of MCP tool requirements."
282
+ )
208
283
  libraries: Tuple[str, ...] = Field(
209
284
  default_factory=tuple, description="List of Python packages required (if code execution is allowed)."
210
285
  )
211
286
 
212
287
 
213
- class PolicyConfig(BaseModel):
288
+ class PolicyConfig(CoReasonBaseModel):
214
289
  """Governance policy configuration.
215
290
 
216
291
  Attributes:
@@ -234,7 +309,7 @@ class TraceLevel(str, Enum):
234
309
  NONE = "none"
235
310
 
236
311
 
237
- class ObservabilityConfig(BaseModel):
312
+ class ObservabilityConfig(CoReasonBaseModel):
238
313
  """Observability configuration.
239
314
 
240
315
  Attributes:
@@ -250,7 +325,7 @@ class ObservabilityConfig(BaseModel):
250
325
  encryption_key_id: Optional[str] = Field(None, description="Optional ID of the key used for log encryption.")
251
326
 
252
327
 
253
- class AgentDefinition(BaseModel):
328
+ class AgentDefinition(CoReasonBaseModel):
254
329
  """The Root Object for the CoReason Agent Manifest.
255
330
 
256
331
  Attributes:
@@ -277,6 +352,9 @@ class AgentDefinition(BaseModel):
277
352
  dependencies: AgentDependencies
278
353
  policy: Optional[PolicyConfig] = Field(None, description="Governance policy configuration.")
279
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
+ )
280
358
  integrity_hash: str = Field(
281
359
  ...,
282
360
  pattern=r"^[a-fA-F0-9]{64}$",
@@ -1,16 +1,29 @@
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
+
1
11
  import hashlib
2
12
  import json
13
+ import uuid
3
14
  from datetime import datetime
4
15
  from enum import Enum
5
16
  from typing import Any, Dict, List, Optional
6
17
  from uuid import UUID
7
18
 
8
- from pydantic import BaseModel, ConfigDict, Field
19
+ from pydantic import ConfigDict, Field
20
+
21
+ from coreason_manifest.definitions.base import CoReasonBaseModel
9
22
 
10
23
  from .message import ChatMessage
11
24
 
12
25
 
13
- class GenAITokenUsage(BaseModel):
26
+ class GenAITokenUsage(CoReasonBaseModel):
14
27
  """Token consumption stats aligned with OTel conventions."""
15
28
 
16
29
  model_config = ConfigDict(extra="ignore")
@@ -25,8 +38,33 @@ class GenAITokenUsage(BaseModel):
25
38
  total_tokens: int = 0
26
39
  details: Dict[str, Any] = Field(default_factory=dict)
27
40
 
28
-
29
- class GenAIOperation(BaseModel):
41
+ def __add__(self, other: "GenAITokenUsage") -> "GenAITokenUsage":
42
+ """Add two TokenUsage objects."""
43
+ new_details = self.details.copy()
44
+ new_details.update(other.details)
45
+ return GenAITokenUsage(
46
+ input=self.input + other.input,
47
+ output=self.output + other.output,
48
+ total=self.total + other.total,
49
+ prompt_tokens=self.prompt_tokens + other.prompt_tokens,
50
+ completion_tokens=self.completion_tokens + other.completion_tokens,
51
+ total_tokens=self.total_tokens + other.total_tokens,
52
+ details=new_details,
53
+ )
54
+
55
+ def __iadd__(self, other: "GenAITokenUsage") -> "GenAITokenUsage":
56
+ """In-place add two TokenUsage objects."""
57
+ self.input += other.input
58
+ self.output += other.output
59
+ self.total += other.total
60
+ self.prompt_tokens += other.prompt_tokens
61
+ self.completion_tokens += other.completion_tokens
62
+ self.total_tokens += other.total_tokens
63
+ self.details.update(other.details)
64
+ return self
65
+
66
+
67
+ class GenAIOperation(CoReasonBaseModel):
30
68
  """An atomic operation in the reasoning process (e.g., one LLM call), aligning with OTel Spans."""
31
69
 
32
70
  model_config = ConfigDict(extra="ignore")
@@ -55,8 +93,26 @@ class GenAIOperation(BaseModel):
55
93
  error_type: Optional[str] = None
56
94
  metadata: Dict[str, Any] = Field(default_factory=dict)
57
95
 
58
-
59
- class ReasoningTrace(BaseModel):
96
+ @classmethod
97
+ def thought(cls, content: str, **kwargs: Any) -> "GenAIOperation":
98
+ """Factory method to create a simplified thought/reasoning step."""
99
+ defaults = {
100
+ "span_id": str(uuid.uuid4()),
101
+ "trace_id": str(uuid.uuid4()),
102
+ "operation_name": "thought",
103
+ "provider": "internal",
104
+ "model": "internal",
105
+ }
106
+ defaults.update(kwargs)
107
+ # Ensure output_messages is not duplicated if passed in kwargs
108
+ defaults.pop("output_messages", None)
109
+ return cls(
110
+ **defaults,
111
+ output_messages=[ChatMessage.assistant(content)],
112
+ )
113
+
114
+
115
+ class ReasoningTrace(CoReasonBaseModel):
60
116
  """The full audit trail of an Agent's execution session.
61
117
 
62
118
  Aligned with OpenTelemetry for trace identification.
@@ -83,6 +139,9 @@ class ReasoningTrace(BaseModel):
83
139
  total_tokens: GenAITokenUsage = Field(default_factory=GenAITokenUsage)
84
140
  total_cost: float = 0.0
85
141
 
142
+ # Flexible metadata
143
+ metadata: Dict[str, Any] = Field(default_factory=dict)
144
+
86
145
 
87
146
  class AuditEventType(str, Enum):
88
147
  SYSTEM_CHANGE = "system_change"
@@ -90,7 +149,7 @@ class AuditEventType(str, Enum):
90
149
  GUARDRAIL_TRIGGER = "guardrail_trigger"
91
150
 
92
151
 
93
- class AuditLog(BaseModel):
152
+ class AuditLog(CoReasonBaseModel):
94
153
  """Tamper-evident legal record.
95
154
 
96
155
  IDs aligned with OpenTelemetry:
@@ -0,0 +1,47 @@
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 typing import Any, Dict
12
+
13
+ from pydantic import BaseModel, ConfigDict
14
+
15
+
16
+ class CoReasonBaseModel(BaseModel):
17
+ """Base model for all CoReason Pydantic models with enhanced serialization.
18
+
19
+ This base class addresses JSON serialization challenges in Pydantic v2 (e.g., UUID, datetime)
20
+ by providing standardized methods (`dump`, `to_json`) with optimal configuration.
21
+
22
+ For a detailed rationale, see `docs/coreason_base_model_rationale.md`.
23
+ """
24
+
25
+ model_config = ConfigDict(populate_by_name=True)
26
+
27
+ def dump(self, **kwargs: Any) -> Dict[str, Any]:
28
+ """Serialize the model to a JSON-compatible dictionary.
29
+
30
+ Uses mode='json' to ensure types like UUID and datetime are serialized to strings.
31
+ Defaults to by_alias=True and exclude_none=True.
32
+ """
33
+ # Set defaults but allow overrides
34
+ kwargs.setdefault("mode", "json")
35
+ kwargs.setdefault("by_alias", True)
36
+ kwargs.setdefault("exclude_none", True)
37
+ return self.model_dump(**kwargs)
38
+
39
+ def to_json(self, **kwargs: Any) -> str:
40
+ """Serialize the model to a JSON string.
41
+
42
+ Defaults to by_alias=True and exclude_none=True.
43
+ """
44
+ # Set defaults but allow overrides
45
+ kwargs.setdefault("by_alias", True)
46
+ kwargs.setdefault("exclude_none", True)
47
+ return self.model_dump_json(**kwargs)