coreason-manifest 0.7.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.
- coreason_manifest/__init__.py +85 -4
- coreason_manifest/definitions/__init__.py +60 -0
- coreason_manifest/definitions/agent.py +177 -38
- coreason_manifest/definitions/audit.py +178 -4
- coreason_manifest/definitions/base.py +47 -0
- coreason_manifest/definitions/events.py +423 -0
- coreason_manifest/definitions/message.py +188 -0
- coreason_manifest/definitions/simulation.py +69 -9
- coreason_manifest/definitions/simulation_config.py +46 -0
- coreason_manifest/definitions/topology.py +210 -9
- coreason_manifest/recipes.py +53 -7
- coreason_manifest/schemas/__init__.py +9 -1
- coreason_manifest/schemas/agent.schema.json +855 -27
- coreason_manifest/schemas/recipe.schema.json +813 -0
- coreason_manifest/utils/__init__.py +10 -0
- coreason_manifest/utils/logger.py +10 -0
- coreason_manifest/v1/__init__.py +15 -0
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.10.0.dist-info}/METADATA +91 -29
- coreason_manifest-0.10.0.dist-info/RECORD +22 -0
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.10.0.dist-info}/WHEEL +1 -1
- coreason_manifest-0.7.0.dist-info/RECORD +0 -16
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.10.0.dist-info}/licenses/LICENSE +0 -0
- {coreason_manifest-0.7.0.dist-info → coreason_manifest-0.10.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,19 +1,79 @@
|
|
|
1
|
-
|
|
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
|
|
2
10
|
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
from uuid import UUID
|
|
3
15
|
|
|
4
|
-
|
|
16
|
+
from pydantic import Field
|
|
17
|
+
|
|
18
|
+
from coreason_manifest.definitions.base import CoReasonBaseModel
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class StepType(str, Enum):
|
|
22
|
+
"""Type of the simulation step."""
|
|
23
|
+
|
|
24
|
+
INTERACTION = "interaction" # Normal User/Agent turn
|
|
25
|
+
SYSTEM_EVENT = "system_event" # Chaos injection, error, or info
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ValidationLogic(str, Enum):
|
|
29
|
+
"""Logic used to validate the scenario outcome."""
|
|
30
|
+
|
|
31
|
+
EXACT_MATCH = "exact_match"
|
|
32
|
+
FUZZY = "fuzzy"
|
|
33
|
+
CODE_EVAL = "code_eval"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SimulationScenario(CoReasonBaseModel):
|
|
5
37
|
"""Definition of a simulation scenario."""
|
|
6
38
|
|
|
7
|
-
|
|
39
|
+
id: str = Field(..., description="Unique identifier for the scenario.")
|
|
40
|
+
name: str = Field(..., description="Name of the scenario.")
|
|
41
|
+
objective: str = Field(..., description="The prompt/task instructions.")
|
|
42
|
+
difficulty: int = Field(..., description="Difficulty level (1-3, aligning with GAIA levels).", ge=1, le=3)
|
|
43
|
+
expected_outcome: Any = Field(..., description="The ground truth for validation.")
|
|
44
|
+
validation_logic: ValidationLogic = Field(..., description="Logic used to validate the outcome.")
|
|
8
45
|
|
|
9
46
|
|
|
10
|
-
class
|
|
11
|
-
"""
|
|
47
|
+
class SimulationStep(CoReasonBaseModel):
|
|
48
|
+
"""The atomic unit of execution in a simulation."""
|
|
49
|
+
|
|
50
|
+
step_id: UUID = Field(..., description="Atomic unit of execution ID.")
|
|
51
|
+
timestamp: datetime = Field(..., description="Execution timestamp.")
|
|
52
|
+
type: StepType = Field(default=StepType.INTERACTION, description="Type of the step.")
|
|
53
|
+
node_id: str = Field(..., description="The graph node executed.")
|
|
54
|
+
inputs: Dict[str, Any] = Field(..., description="Snapshot of entry state.")
|
|
55
|
+
thought: Optional[str] = Field(None, description="The Chain-of-Thought reasoning.")
|
|
56
|
+
action: Optional[Dict[str, Any]] = Field(None, description="Tool calls or API requests.")
|
|
57
|
+
observation: Optional[Dict[str, Any]] = Field(None, description="Tool outputs.")
|
|
58
|
+
snapshot: Dict[str, Any] = Field(
|
|
59
|
+
default_factory=dict, description="Full copy of the graph state at the completion of this step."
|
|
60
|
+
)
|
|
12
61
|
|
|
13
|
-
pass
|
|
14
62
|
|
|
63
|
+
class SimulationMetrics(CoReasonBaseModel):
|
|
64
|
+
"""Metrics gathered during simulation."""
|
|
15
65
|
|
|
16
|
-
|
|
17
|
-
|
|
66
|
+
turn_count: int
|
|
67
|
+
total_tokens: Optional[int] = None
|
|
68
|
+
cost_usd: Optional[float] = None
|
|
69
|
+
duration_ms: Optional[float] = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class SimulationTrace(CoReasonBaseModel):
|
|
73
|
+
"""Trace of a simulation execution."""
|
|
18
74
|
|
|
19
|
-
|
|
75
|
+
trace_id: UUID = Field(..., description="Unique trace identifier.")
|
|
76
|
+
agent_version: str = Field(..., description="Agent SemVer version.")
|
|
77
|
+
steps: List[SimulationStep] = Field(..., description="List of execution steps.")
|
|
78
|
+
outcome: Dict[str, Any] = Field(..., description="Final result.")
|
|
79
|
+
metrics: SimulationMetrics = Field(..., description="Execution metrics (e.g., token usage, cost).")
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from pydantic import Field
|
|
15
|
+
|
|
16
|
+
from coreason_manifest.definitions.agent import Persona
|
|
17
|
+
from coreason_manifest.definitions.base import CoReasonBaseModel
|
|
18
|
+
from coreason_manifest.definitions.simulation import SimulationScenario
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AdversaryProfile(CoReasonBaseModel):
|
|
22
|
+
name: str
|
|
23
|
+
goal: str
|
|
24
|
+
strategy_model: str # e.g., "claude-3-opus"
|
|
25
|
+
attack_model: str # e.g., "llama-3-uncensored"
|
|
26
|
+
persona: Optional[Persona] = Field(None, description="The full persona definition (name, description, directives).")
|
|
27
|
+
# Potential future field: 'system_prompt_override'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ChaosConfig(CoReasonBaseModel):
|
|
31
|
+
latency_ms: int = Field(default=0, ge=0)
|
|
32
|
+
error_rate: float = Field(default=0.0, ge=0.0, le=1.0)
|
|
33
|
+
noise_rate: float = Field(default=0.0, ge=0.0, le=1.0)
|
|
34
|
+
token_throttle: bool = False
|
|
35
|
+
exception_type: str = "RuntimeError"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SimulationRequest(CoReasonBaseModel):
|
|
39
|
+
"""
|
|
40
|
+
Standard payload for triggering a simulation.
|
|
41
|
+
This would replace the local 'SimulationRequest' in the Simulator.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
scenario: SimulationScenario
|
|
45
|
+
profile: AdversaryProfile
|
|
46
|
+
chaos_config: ChaosConfig = Field(default_factory=ChaosConfig)
|
|
@@ -1,3 +1,13 @@
|
|
|
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
|
# Copyright (c) 2025 CoReason, Inc.
|
|
2
12
|
#
|
|
3
13
|
# This software is proprietary and dual-licensed.
|
|
@@ -8,12 +18,33 @@
|
|
|
8
18
|
#
|
|
9
19
|
# Source Code: https://github.com/CoReason-AI/coreason_maco
|
|
10
20
|
|
|
11
|
-
from
|
|
21
|
+
from enum import Enum
|
|
22
|
+
from typing import Annotated, Any, Dict, List, Literal, Optional, Sequence, Union
|
|
23
|
+
|
|
24
|
+
from pydantic import ConfigDict, Field, StringConstraints, model_validator
|
|
25
|
+
|
|
26
|
+
from coreason_manifest.definitions.base import CoReasonBaseModel
|
|
12
27
|
|
|
13
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
14
28
|
|
|
29
|
+
class StateDefinition(CoReasonBaseModel):
|
|
30
|
+
"""Defines the internal state (memory) of the Recipe.
|
|
15
31
|
|
|
16
|
-
|
|
32
|
+
Attributes:
|
|
33
|
+
schema: JSON Schema of the keys available in the shared memory.
|
|
34
|
+
persistence: Configuration for state durability.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
model_config = ConfigDict(extra="forbid")
|
|
38
|
+
|
|
39
|
+
schema_: Dict[str, Any] = Field(
|
|
40
|
+
..., alias="schema", description="JSON Schema of the keys available in the shared memory."
|
|
41
|
+
)
|
|
42
|
+
persistence: Literal["ephemeral", "persistent"] = Field(
|
|
43
|
+
default="ephemeral", description="Configuration for state durability."
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CouncilConfig(CoReasonBaseModel):
|
|
17
48
|
"""Configuration for 'Architectural Triangulation'.
|
|
18
49
|
|
|
19
50
|
Attributes:
|
|
@@ -27,7 +58,7 @@ class CouncilConfig(BaseModel):
|
|
|
27
58
|
voters: List[str] = Field(..., description="List of agents or models that vote.")
|
|
28
59
|
|
|
29
60
|
|
|
30
|
-
class VisualMetadata(
|
|
61
|
+
class VisualMetadata(CoReasonBaseModel):
|
|
31
62
|
"""Data explicitly for the UI.
|
|
32
63
|
|
|
33
64
|
Attributes:
|
|
@@ -47,13 +78,28 @@ class VisualMetadata(BaseModel):
|
|
|
47
78
|
animation_style: Optional[str] = Field(None, description="The animation style for the node.")
|
|
48
79
|
|
|
49
80
|
|
|
50
|
-
class
|
|
81
|
+
class RuntimeVisualMetadata(VisualMetadata):
|
|
82
|
+
"""Visual metadata with runtime extensions.
|
|
83
|
+
|
|
84
|
+
Attributes:
|
|
85
|
+
color: Color override for the node (e.g., '#00FF00').
|
|
86
|
+
progress: Progress indicator (e.g., '0.5' or '50%').
|
|
87
|
+
animation: Animation override (e.g., 'pulse').
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
color: Optional[str] = Field(None, description="Color override for the node.")
|
|
91
|
+
progress: Optional[str] = Field(None, description="Progress indicator.")
|
|
92
|
+
animation: Optional[str] = Field(None, description="Animation override.")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class BaseNode(CoReasonBaseModel):
|
|
51
96
|
"""Base model for all node types.
|
|
52
97
|
|
|
53
98
|
Attributes:
|
|
54
99
|
id: Unique identifier for the node.
|
|
55
100
|
council_config: Optional configuration for architectural triangulation.
|
|
56
101
|
visual: Visual metadata for the UI.
|
|
102
|
+
metadata: Generic metadata for operational context (e.g. cost tracking, SLAs).
|
|
57
103
|
"""
|
|
58
104
|
|
|
59
105
|
model_config = ConfigDict(extra="forbid")
|
|
@@ -63,6 +109,10 @@ class BaseNode(BaseModel):
|
|
|
63
109
|
None, description="Optional configuration for architectural triangulation."
|
|
64
110
|
)
|
|
65
111
|
visual: Optional[VisualMetadata] = Field(None, description="Visual metadata for the UI.")
|
|
112
|
+
metadata: Dict[str, Any] = Field(
|
|
113
|
+
default_factory=dict,
|
|
114
|
+
description="Generic metadata for operational context (e.g. cost tracking, SLAs).",
|
|
115
|
+
)
|
|
66
116
|
|
|
67
117
|
|
|
68
118
|
class AgentNode(BaseNode):
|
|
@@ -71,10 +121,27 @@ class AgentNode(BaseNode):
|
|
|
71
121
|
Attributes:
|
|
72
122
|
type: The type of the node (must be 'agent').
|
|
73
123
|
agent_name: The name of the atomic agent to call.
|
|
124
|
+
system_prompt: Overrides the registry default prompt. Required for ad-hoc/optimized agents.
|
|
125
|
+
config: Runtime-specific configuration (e.g., model parameters, temperature). Merged with registry defaults.
|
|
126
|
+
overrides: Runtime overrides for the agent (e.g., temperature, prompt_template_vars).
|
|
74
127
|
"""
|
|
75
128
|
|
|
76
129
|
type: Literal["agent"] = Field("agent", description="Discriminator for AgentNode.")
|
|
77
130
|
agent_name: str = Field(..., description="The name of the atomic agent to call.")
|
|
131
|
+
system_prompt: Optional[str] = Field(
|
|
132
|
+
default=None,
|
|
133
|
+
description="Overrides the registry default prompt. Required for ad-hoc/optimized agents.",
|
|
134
|
+
)
|
|
135
|
+
config: Optional[Dict[str, Any]] = Field(
|
|
136
|
+
default=None,
|
|
137
|
+
description=(
|
|
138
|
+
"Runtime-specific configuration (e.g., model parameters, temperature). Merged with registry defaults."
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
overrides: Optional[Dict[str, Any]] = Field(
|
|
142
|
+
default=None,
|
|
143
|
+
description="Runtime overrides for the agent (e.g., temperature, prompt_template_vars).",
|
|
144
|
+
)
|
|
78
145
|
|
|
79
146
|
|
|
80
147
|
class HumanNode(BaseNode):
|
|
@@ -101,13 +168,67 @@ class LogicNode(BaseNode):
|
|
|
101
168
|
code: str = Field(..., description="The Python logic code to execute.")
|
|
102
169
|
|
|
103
170
|
|
|
171
|
+
class DataMappingStrategy(str, Enum):
|
|
172
|
+
"""Strategy for mapping data."""
|
|
173
|
+
|
|
174
|
+
DIRECT = "direct"
|
|
175
|
+
JSONPATH = "jsonpath"
|
|
176
|
+
LITERAL = "literal"
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class DataMapping(CoReasonBaseModel):
|
|
180
|
+
"""Defines how to transform data between parent and child."""
|
|
181
|
+
|
|
182
|
+
model_config = ConfigDict(extra="forbid")
|
|
183
|
+
|
|
184
|
+
source: str = Field(..., description="The path/key source.")
|
|
185
|
+
strategy: DataMappingStrategy = Field(default=DataMappingStrategy.DIRECT, description="The mapping strategy.")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class RecipeNode(BaseNode):
|
|
189
|
+
"""A node that executes another Recipe as a sub-graph.
|
|
190
|
+
|
|
191
|
+
Attributes:
|
|
192
|
+
type: The type of the node (must be 'recipe').
|
|
193
|
+
recipe_id: The ID of the recipe to execute.
|
|
194
|
+
input_mapping: How parent state maps to child inputs (parent_key -> child_key).
|
|
195
|
+
output_mapping: How child result maps back to parent state (child_key -> parent_key).
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
type: Literal["recipe"] = Field("recipe", description="Discriminator for RecipeNode.")
|
|
199
|
+
recipe_id: str = Field(..., description="The ID of the recipe to execute.")
|
|
200
|
+
input_mapping: Dict[str, Union[str, DataMapping]] = Field(
|
|
201
|
+
..., description="Mapping of parent state keys to child input keys."
|
|
202
|
+
)
|
|
203
|
+
output_mapping: Dict[str, Union[str, DataMapping]] = Field(
|
|
204
|
+
..., description="Mapping of child output keys to parent state keys."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class MapNode(BaseNode):
|
|
209
|
+
"""A node that spawns multiple parallel executions of a sub-branch.
|
|
210
|
+
|
|
211
|
+
Attributes:
|
|
212
|
+
type: The type of the node (must be 'map').
|
|
213
|
+
items_path: Dot-notation path to the list in the state.
|
|
214
|
+
processor_node_id: The node (or subgraph) to run for each item.
|
|
215
|
+
concurrency_limit: Max parallel executions.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
type: Literal["map"] = Field("map", description="Discriminator for MapNode.")
|
|
219
|
+
items_path: str = Field(..., description="Dot-notation path to the list in the state.")
|
|
220
|
+
processor_node_id: str = Field(..., description="The node (or subgraph) to run for each item.")
|
|
221
|
+
concurrency_limit: int = Field(..., description="Max parallel executions.")
|
|
222
|
+
|
|
223
|
+
|
|
104
224
|
# Discriminated Union for polymorphism
|
|
105
225
|
Node = Annotated[
|
|
106
|
-
Union[AgentNode, HumanNode, LogicNode
|
|
226
|
+
Union[AgentNode, HumanNode, LogicNode, RecipeNode, MapNode],
|
|
227
|
+
Field(discriminator="type", description="Polymorphic node definition."),
|
|
107
228
|
]
|
|
108
229
|
|
|
109
230
|
|
|
110
|
-
class Edge(
|
|
231
|
+
class Edge(CoReasonBaseModel):
|
|
111
232
|
"""Represents a connection between two nodes.
|
|
112
233
|
|
|
113
234
|
Attributes:
|
|
@@ -123,18 +244,98 @@ class Edge(BaseModel):
|
|
|
123
244
|
condition: Optional[str] = Field(None, description="Optional Python expression for conditional branching.")
|
|
124
245
|
|
|
125
246
|
|
|
126
|
-
|
|
247
|
+
RouterRef = Annotated[
|
|
248
|
+
str,
|
|
249
|
+
StringConstraints(
|
|
250
|
+
pattern=r"^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$",
|
|
251
|
+
strip_whitespace=True,
|
|
252
|
+
),
|
|
253
|
+
]
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class RouterExpression(CoReasonBaseModel):
|
|
257
|
+
"""A structured expression for routing logic (e.g., CEL or JSONLogic)."""
|
|
258
|
+
|
|
259
|
+
model_config = ConfigDict(extra="forbid")
|
|
260
|
+
|
|
261
|
+
operator: str = Field(..., description="The operator (e.g., 'eq', 'gt').")
|
|
262
|
+
args: List[Any] = Field(..., description="Arguments for the expression.")
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
RouterDefinition = Annotated[
|
|
266
|
+
Union[RouterRef, RouterExpression],
|
|
267
|
+
Field(description="A reference to a python function or a logic expression."),
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class ConditionalEdge(CoReasonBaseModel):
|
|
272
|
+
"""Represents a dynamic routing connection from one node to multiple potential targets.
|
|
273
|
+
|
|
274
|
+
Attributes:
|
|
275
|
+
source_node_id: The ID of the source node.
|
|
276
|
+
router_logic: A reference to a python function or a logic expression that returns the next node ID.
|
|
277
|
+
mapping: A dictionary mapping the router's output (e.g., "approve", "reject") to target Node IDs.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
model_config = ConfigDict(extra="forbid")
|
|
281
|
+
|
|
282
|
+
source_node_id: str = Field(..., description="The ID of the source node.")
|
|
283
|
+
router_logic: RouterDefinition = Field(
|
|
284
|
+
..., description="A reference to a python function or logic expression that determines the path."
|
|
285
|
+
)
|
|
286
|
+
mapping: Dict[str, str] = Field(..., description="Map of router output values to target node IDs.")
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def validate_edge_integrity(
|
|
290
|
+
nodes: Sequence[Node],
|
|
291
|
+
edges: Sequence[Union[Edge, ConditionalEdge]],
|
|
292
|
+
) -> None:
|
|
293
|
+
"""Ensures that all edges point to valid nodes.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
nodes: List of nodes in the graph.
|
|
297
|
+
edges: List of edges connecting the nodes.
|
|
298
|
+
|
|
299
|
+
Raises:
|
|
300
|
+
ValueError: If an edge points to a non-existent node.
|
|
301
|
+
"""
|
|
302
|
+
node_ids = {node.id for node in nodes}
|
|
303
|
+
|
|
304
|
+
for edge in edges:
|
|
305
|
+
if edge.source_node_id not in node_ids:
|
|
306
|
+
raise ValueError(f"Edge source node '{edge.source_node_id}' not found in nodes.")
|
|
307
|
+
|
|
308
|
+
# ConditionalEdge mapping targets
|
|
309
|
+
if isinstance(edge, ConditionalEdge):
|
|
310
|
+
for target_id in edge.mapping.values():
|
|
311
|
+
if target_id not in node_ids:
|
|
312
|
+
raise ValueError(f"ConditionalEdge target node '{target_id}' not found in nodes.")
|
|
313
|
+
else:
|
|
314
|
+
# Regular Edge
|
|
315
|
+
if edge.target_node_id not in node_ids:
|
|
316
|
+
raise ValueError(f"Edge target node '{edge.target_node_id}' not found in nodes.")
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
class GraphTopology(CoReasonBaseModel):
|
|
127
320
|
"""The topology definition of the recipe.
|
|
128
321
|
|
|
129
322
|
Attributes:
|
|
130
323
|
nodes: List of nodes in the graph.
|
|
131
324
|
edges: List of edges connecting the nodes.
|
|
325
|
+
state_schema: Optional schema definition for the graph state.
|
|
132
326
|
"""
|
|
133
327
|
|
|
134
328
|
model_config = ConfigDict(extra="forbid")
|
|
135
329
|
|
|
136
330
|
nodes: List[Node] = Field(..., description="List of nodes in the graph.")
|
|
137
|
-
edges: List[Edge] = Field(..., description="List of edges connecting the nodes.")
|
|
331
|
+
edges: List[Union[Edge, ConditionalEdge]] = Field(..., description="List of edges connecting the nodes.")
|
|
332
|
+
state_schema: Optional[StateDefinition] = Field(default=None, description="Schema definition for the graph state.")
|
|
333
|
+
|
|
334
|
+
@model_validator(mode="after")
|
|
335
|
+
def validate_graph_integrity(self) -> "GraphTopology":
|
|
336
|
+
"""Ensures that all edges point to valid nodes."""
|
|
337
|
+
validate_edge_integrity(self.nodes, self.edges)
|
|
338
|
+
return self
|
|
138
339
|
|
|
139
340
|
|
|
140
341
|
Topology = GraphTopology
|
coreason_manifest/recipes.py
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
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
|
# Copyright (c) 2025 CoReason, Inc.
|
|
2
12
|
#
|
|
3
13
|
# This software is proprietary and dual-licensed.
|
|
@@ -10,13 +20,30 @@
|
|
|
10
20
|
|
|
11
21
|
from typing import Any, Dict, Optional
|
|
12
22
|
|
|
13
|
-
from pydantic import
|
|
23
|
+
from pydantic import ConfigDict, Field
|
|
14
24
|
|
|
15
25
|
from .definitions.agent import VersionStr
|
|
16
|
-
from .definitions.
|
|
26
|
+
from .definitions.base import CoReasonBaseModel
|
|
27
|
+
from .definitions.topology import GraphTopology, StateDefinition
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class RecipeInterface(CoReasonBaseModel):
|
|
31
|
+
"""Defines the input/output contract for a Recipe.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
inputs: JSON Schema defining valid entry arguments.
|
|
35
|
+
outputs: JSON Schema defining the guaranteed structure of the final result.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
model_config = ConfigDict(extra="forbid")
|
|
39
|
+
|
|
40
|
+
inputs: Dict[str, Any] = Field(..., description="JSON Schema defining valid entry arguments.")
|
|
41
|
+
outputs: Dict[str, Any] = Field(
|
|
42
|
+
..., description="JSON Schema defining the guaranteed structure of the final result."
|
|
43
|
+
)
|
|
17
44
|
|
|
18
45
|
|
|
19
|
-
class RecipeManifest(
|
|
46
|
+
class RecipeManifest(CoReasonBaseModel):
|
|
20
47
|
"""The executable specification for the MACO engine.
|
|
21
48
|
|
|
22
49
|
Attributes:
|
|
@@ -24,8 +51,12 @@ class RecipeManifest(BaseModel):
|
|
|
24
51
|
version: Version of the recipe.
|
|
25
52
|
name: Human-readable name of the recipe.
|
|
26
53
|
description: Detailed description of the recipe.
|
|
27
|
-
|
|
28
|
-
|
|
54
|
+
interface: Defines the input/output contract for the Recipe.
|
|
55
|
+
state: Defines the internal state (memory) of the Recipe.
|
|
56
|
+
parameters: Dictionary of build-time constants.
|
|
57
|
+
topology: The topology definition of the workflow.
|
|
58
|
+
integrity_hash: SHA256 hash of the canonical JSON representation of the topology.
|
|
59
|
+
metadata: Container for design-time data.
|
|
29
60
|
"""
|
|
30
61
|
|
|
31
62
|
model_config = ConfigDict(extra="forbid")
|
|
@@ -34,5 +65,20 @@ class RecipeManifest(BaseModel):
|
|
|
34
65
|
version: VersionStr = Field(..., description="Version of the recipe.")
|
|
35
66
|
name: str = Field(..., description="Human-readable name of the recipe.")
|
|
36
67
|
description: Optional[str] = Field(None, description="Detailed description of the recipe.")
|
|
37
|
-
|
|
38
|
-
|
|
68
|
+
interface: RecipeInterface = Field(..., description="Defines the input/output contract for the Recipe.")
|
|
69
|
+
state: StateDefinition = Field(..., description="Defines the internal state (memory) of the Recipe.")
|
|
70
|
+
parameters: Dict[str, Any] = Field(..., description="Dictionary of build-time constants.")
|
|
71
|
+
topology: GraphTopology = Field(..., description="The topology definition of the workflow.")
|
|
72
|
+
integrity_hash: Optional[str] = Field(
|
|
73
|
+
default=None,
|
|
74
|
+
description=(
|
|
75
|
+
"SHA256 hash of the canonical JSON representation of the topology. "
|
|
76
|
+
"Enforced by Builder, verified by Runtime."
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
metadata: Dict[str, Any] = Field(
|
|
80
|
+
default_factory=dict,
|
|
81
|
+
description=(
|
|
82
|
+
"Container for design-time data (UI coordinates, resolution logs, draft status) to support re-hydration."
|
|
83
|
+
),
|
|
84
|
+
)
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
#
|
|
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
|