coreason-manifest 0.12.0__tar.gz → 0.15.0__tar.gz
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-0.12.0 → coreason_manifest-0.15.0}/PKG-INFO +1 -2
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/pyproject.toml +2 -3
- coreason_manifest-0.15.0/src/coreason_manifest/__init__.py +97 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/common.py +2 -2
- coreason_manifest-0.15.0/src/coreason_manifest/definitions/identity.py +33 -0
- coreason_manifest-0.15.0/src/coreason_manifest/definitions/message.py +41 -0
- coreason_manifest-0.15.0/src/coreason_manifest/definitions/presentation.py +52 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/governance.py +2 -0
- coreason_manifest-0.15.0/src/coreason_manifest/spec/cap.py +115 -0
- coreason_manifest-0.15.0/src/coreason_manifest/utils/logger.py +13 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/governance.py +5 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/resolver.py +1 -3
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/contracts.py +8 -6
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/definitions.py +10 -61
- coreason_manifest-0.15.0/src/coreason_manifest/v2/validator.py +195 -0
- coreason_manifest-0.12.0/src/coreason_manifest/__init__.py +0 -51
- coreason_manifest-0.12.0/src/coreason_manifest/utils/logger.py +0 -58
- coreason_manifest-0.12.0/src/coreason_manifest/v2/validator.py +0 -48
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/LICENSE +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/NOTICE +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/README.md +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/schemas/__init__.py +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/schemas/coreason-v2.schema.json +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/utils/__init__.py +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/__init__.py +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/io.py +0 -0
- {coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coreason_manifest
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.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,6 @@ Requires-Python: >=3.12
|
|
|
67
67
|
Classifier: License :: Other/Proprietary License
|
|
68
68
|
Classifier: Programming Language :: Python :: 3.12
|
|
69
69
|
Classifier: Operating System :: OS Independent
|
|
70
|
-
Requires-Dist: coreason-identity (>=0.4.1,<0.5.0)
|
|
71
70
|
Requires-Dist: jsonschema (>=4.19.0,<5.0.0)
|
|
72
71
|
Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
|
73
72
|
Requires-Dist: pydantic (>=2.12.5,<3.0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "coreason_manifest"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.15.0"
|
|
4
4
|
description = "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
|
authors = ["Gowtham A Rao <gowtham.rao@coreason.ai>"]
|
|
6
6
|
license = "Prosperity-3.0"
|
|
@@ -12,7 +12,6 @@ python = ">=3.12, <3.15"
|
|
|
12
12
|
loguru = "^0.7.2"
|
|
13
13
|
pydantic = "^2.12.5"
|
|
14
14
|
pyyaml = "^6.0.3"
|
|
15
|
-
coreason-identity = "^0.4.1"
|
|
16
15
|
jsonschema = "^4.19.0"
|
|
17
16
|
|
|
18
17
|
[tool.poetry.group.dev.dependencies]
|
|
@@ -33,7 +32,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
33
32
|
|
|
34
33
|
[project]
|
|
35
34
|
name = "coreason_manifest"
|
|
36
|
-
version = "0.
|
|
35
|
+
version = "0.15.0"
|
|
37
36
|
description = "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."
|
|
38
37
|
readme = "README.md"
|
|
39
38
|
requires-python = ">=3.12"
|
|
@@ -0,0 +1,97 @@
|
|
|
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 .common import ToolRiskLevel
|
|
12
|
+
from .definitions.identity import Identity
|
|
13
|
+
from .definitions.message import ChatMessage, Role
|
|
14
|
+
from .definitions.presentation import (
|
|
15
|
+
AnyPresentationEvent,
|
|
16
|
+
ArtifactEvent,
|
|
17
|
+
CitationEvent,
|
|
18
|
+
PresentationEvent,
|
|
19
|
+
PresentationEventType,
|
|
20
|
+
)
|
|
21
|
+
from .governance import ComplianceReport, ComplianceViolation, GovernanceConfig
|
|
22
|
+
from .spec.cap import (
|
|
23
|
+
ErrorSeverity,
|
|
24
|
+
HealthCheckResponse,
|
|
25
|
+
HealthCheckStatus,
|
|
26
|
+
ServiceRequest,
|
|
27
|
+
ServiceResponse,
|
|
28
|
+
StreamError,
|
|
29
|
+
StreamOpCode,
|
|
30
|
+
StreamPacket,
|
|
31
|
+
)
|
|
32
|
+
from .v2.governance import check_compliance_v2
|
|
33
|
+
from .v2.io import dump_to_yaml, load_from_yaml
|
|
34
|
+
from .v2.spec.contracts import InterfaceDefinition, PolicyDefinition, StateDefinition
|
|
35
|
+
from .v2.spec.definitions import (
|
|
36
|
+
AgentDefinition,
|
|
37
|
+
AgentStep,
|
|
38
|
+
CouncilStep,
|
|
39
|
+
LogicStep,
|
|
40
|
+
ManifestMetadata,
|
|
41
|
+
ManifestV2,
|
|
42
|
+
Step,
|
|
43
|
+
SwitchStep,
|
|
44
|
+
ToolDefinition,
|
|
45
|
+
Workflow,
|
|
46
|
+
)
|
|
47
|
+
from .v2.validator import validate_integrity, validate_loose
|
|
48
|
+
|
|
49
|
+
__version__ = "0.15.0"
|
|
50
|
+
|
|
51
|
+
Manifest = ManifestV2
|
|
52
|
+
Recipe = ManifestV2
|
|
53
|
+
load = load_from_yaml
|
|
54
|
+
dump = dump_to_yaml
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
"Manifest",
|
|
58
|
+
"Recipe",
|
|
59
|
+
"load",
|
|
60
|
+
"dump",
|
|
61
|
+
"__version__",
|
|
62
|
+
"ManifestMetadata",
|
|
63
|
+
"AgentStep",
|
|
64
|
+
"Workflow",
|
|
65
|
+
"AgentDefinition",
|
|
66
|
+
"ToolDefinition",
|
|
67
|
+
"Step",
|
|
68
|
+
"LogicStep",
|
|
69
|
+
"SwitchStep",
|
|
70
|
+
"CouncilStep",
|
|
71
|
+
"InterfaceDefinition",
|
|
72
|
+
"StateDefinition",
|
|
73
|
+
"PolicyDefinition",
|
|
74
|
+
"ToolRiskLevel",
|
|
75
|
+
"GovernanceConfig",
|
|
76
|
+
"ComplianceReport",
|
|
77
|
+
"ComplianceViolation",
|
|
78
|
+
"Identity",
|
|
79
|
+
"Role",
|
|
80
|
+
"ChatMessage",
|
|
81
|
+
"PresentationEventType",
|
|
82
|
+
"PresentationEvent",
|
|
83
|
+
"AnyPresentationEvent",
|
|
84
|
+
"CitationEvent",
|
|
85
|
+
"ArtifactEvent",
|
|
86
|
+
"HealthCheckResponse",
|
|
87
|
+
"HealthCheckStatus",
|
|
88
|
+
"ServiceRequest",
|
|
89
|
+
"ServiceResponse",
|
|
90
|
+
"StreamPacket",
|
|
91
|
+
"StreamError",
|
|
92
|
+
"StreamOpCode",
|
|
93
|
+
"ErrorSeverity",
|
|
94
|
+
"validate_integrity",
|
|
95
|
+
"validate_loose",
|
|
96
|
+
"check_compliance_v2",
|
|
97
|
+
]
|
|
@@ -32,8 +32,8 @@ class CoReasonBaseModel(BaseModel):
|
|
|
32
32
|
Uses mode='json' to ensure types like UUID and datetime are serialized to strings.
|
|
33
33
|
Defaults to by_alias=True and exclude_none=True.
|
|
34
34
|
"""
|
|
35
|
-
#
|
|
36
|
-
kwargs
|
|
35
|
+
# Strict enforcement of json mode for zero-friction serialization
|
|
36
|
+
kwargs["mode"] = "json"
|
|
37
37
|
kwargs.setdefault("by_alias", True)
|
|
38
38
|
kwargs.setdefault("exclude_none", True)
|
|
39
39
|
return self.model_dump(**kwargs)
|
|
@@ -0,0 +1,33 @@
|
|
|
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 Optional
|
|
12
|
+
|
|
13
|
+
from pydantic import ConfigDict, Field
|
|
14
|
+
|
|
15
|
+
from ..common import CoReasonBaseModel
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Identity(CoReasonBaseModel):
|
|
19
|
+
"""A pure, frozen data structure representing an actor (user, agent, system)."""
|
|
20
|
+
|
|
21
|
+
model_config = ConfigDict(frozen=True)
|
|
22
|
+
|
|
23
|
+
id: str = Field(..., description="Unique identifier for the actor (e.g., UUID, slug).")
|
|
24
|
+
name: str = Field(..., description="Human-readable display name.")
|
|
25
|
+
role: Optional[str] = Field(None, description="Contextual role (e.g., 'user', 'assistant', 'system').")
|
|
26
|
+
|
|
27
|
+
def __str__(self) -> str:
|
|
28
|
+
return f"{self.name} ({self.id})"
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def anonymous(cls) -> "Identity":
|
|
32
|
+
"""Factory method for a standardized anonymous identity."""
|
|
33
|
+
return cls(id="anonymous", name="Anonymous User", role="user")
|
|
@@ -0,0 +1,41 @@
|
|
|
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 datetime import datetime, timezone
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
from pydantic import ConfigDict, Field
|
|
16
|
+
|
|
17
|
+
from ..common import CoReasonBaseModel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Role(str, Enum):
|
|
21
|
+
"""The role of the message sender."""
|
|
22
|
+
|
|
23
|
+
SYSTEM = "system"
|
|
24
|
+
USER = "user"
|
|
25
|
+
ASSISTANT = "assistant"
|
|
26
|
+
TOOL = "tool"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ChatMessage(CoReasonBaseModel):
|
|
30
|
+
"""A single message in a conversation."""
|
|
31
|
+
|
|
32
|
+
model_config = ConfigDict(frozen=True)
|
|
33
|
+
|
|
34
|
+
role: Role = Field(..., description="The role of the message sender.")
|
|
35
|
+
content: str = Field(..., description="The content of the message.")
|
|
36
|
+
name: Optional[str] = Field(None, description="The name of the author of this message.")
|
|
37
|
+
tool_call_id: Optional[str] = Field(None, description="The tool call ID this message is responding to.")
|
|
38
|
+
timestamp: datetime = Field(
|
|
39
|
+
default_factory=lambda: datetime.now(timezone.utc),
|
|
40
|
+
description="The timestamp of the message.",
|
|
41
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
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 enum import Enum
|
|
12
|
+
from typing import List, Literal, Optional, Union
|
|
13
|
+
|
|
14
|
+
from pydantic import ConfigDict, Field
|
|
15
|
+
|
|
16
|
+
from ..common import CoReasonBaseModel
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PresentationEventType(str, Enum):
|
|
20
|
+
"""Types of presentation events."""
|
|
21
|
+
|
|
22
|
+
CITATION = "citation"
|
|
23
|
+
ARTIFACT = "artifact"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class PresentationEvent(CoReasonBaseModel):
|
|
27
|
+
"""Base class for presentation events."""
|
|
28
|
+
|
|
29
|
+
model_config = ConfigDict(frozen=True)
|
|
30
|
+
|
|
31
|
+
type: PresentationEventType = Field(..., description="The type of presentation event.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CitationEvent(PresentationEvent):
|
|
35
|
+
"""An event representing a citation."""
|
|
36
|
+
|
|
37
|
+
type: Literal[PresentationEventType.CITATION] = PresentationEventType.CITATION
|
|
38
|
+
uri: str = Field(..., description="The source URI.")
|
|
39
|
+
text: str = Field(..., description="The quoted text.")
|
|
40
|
+
indices: Optional[List[int]] = Field(None, description="Start and end character indices.")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ArtifactEvent(PresentationEvent):
|
|
44
|
+
"""An event representing a generated artifact."""
|
|
45
|
+
|
|
46
|
+
type: Literal[PresentationEventType.ARTIFACT] = PresentationEventType.ARTIFACT
|
|
47
|
+
artifact_id: str = Field(..., description="Unique ID of the artifact.")
|
|
48
|
+
mime_type: str = Field(..., description="MIME type of the artifact.")
|
|
49
|
+
url: Optional[str] = Field(None, description="Download URL if applicable.")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
AnyPresentationEvent = Union[CitationEvent, ArtifactEvent]
|
|
@@ -60,6 +60,7 @@ class ComplianceViolation(CoReasonBaseModel):
|
|
|
60
60
|
rule: Name of the rule broken.
|
|
61
61
|
message: Human readable details.
|
|
62
62
|
component_id: Name of the tool or component causing the issue.
|
|
63
|
+
severity: Severity level (e.g., 'error', 'warning').
|
|
63
64
|
"""
|
|
64
65
|
|
|
65
66
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
@@ -67,6 +68,7 @@ class ComplianceViolation(CoReasonBaseModel):
|
|
|
67
68
|
rule: str = Field(..., description="Name of the rule broken, e.g., 'domain_restriction'.")
|
|
68
69
|
message: str = Field(..., description="Human readable details.")
|
|
69
70
|
component_id: Optional[str] = Field(None, description="Name of the tool or component causing the issue.")
|
|
71
|
+
severity: Optional[str] = Field(None, description="Severity level (e.g., 'error', 'warning').")
|
|
70
72
|
|
|
71
73
|
|
|
72
74
|
class ComplianceReport(CoReasonBaseModel):
|
|
@@ -0,0 +1,115 @@
|
|
|
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 datetime import datetime
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import Any, Dict, Optional, Union
|
|
14
|
+
from uuid import UUID
|
|
15
|
+
|
|
16
|
+
from pydantic import ConfigDict, Field, model_validator
|
|
17
|
+
|
|
18
|
+
from coreason_manifest.common import CoReasonBaseModel
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HealthCheckStatus(str, Enum):
|
|
22
|
+
"""Status of the health check."""
|
|
23
|
+
|
|
24
|
+
OK = "ok"
|
|
25
|
+
DEGRADED = "degraded"
|
|
26
|
+
MAINTENANCE = "maintenance"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class HealthCheckResponse(CoReasonBaseModel):
|
|
30
|
+
"""Response for a health check request."""
|
|
31
|
+
|
|
32
|
+
model_config = ConfigDict(frozen=True)
|
|
33
|
+
|
|
34
|
+
status: HealthCheckStatus
|
|
35
|
+
agent_id: UUID
|
|
36
|
+
version: str
|
|
37
|
+
uptime_seconds: float
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ErrorSeverity(str, Enum):
|
|
41
|
+
"""Severity of a stream error."""
|
|
42
|
+
|
|
43
|
+
TRANSIENT = "transient"
|
|
44
|
+
FATAL = "fatal"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class StreamOpCode(str, Enum):
|
|
48
|
+
"""Operation code for a stream packet."""
|
|
49
|
+
|
|
50
|
+
DELTA = "delta"
|
|
51
|
+
EVENT = "event"
|
|
52
|
+
ERROR = "error"
|
|
53
|
+
CLOSE = "close"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class StreamError(CoReasonBaseModel):
|
|
57
|
+
"""Strict error model for stream exceptions."""
|
|
58
|
+
|
|
59
|
+
model_config = ConfigDict(frozen=True)
|
|
60
|
+
|
|
61
|
+
code: str
|
|
62
|
+
message: str
|
|
63
|
+
severity: ErrorSeverity
|
|
64
|
+
details: Optional[Dict[str, Any]] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class StreamPacket(CoReasonBaseModel):
|
|
68
|
+
"""A packet of data streaming from an agent."""
|
|
69
|
+
|
|
70
|
+
model_config = ConfigDict(frozen=True)
|
|
71
|
+
|
|
72
|
+
op: StreamOpCode
|
|
73
|
+
p: Union[StreamError, str, Dict[str, Any], None] = Field(union_mode="left_to_right")
|
|
74
|
+
|
|
75
|
+
@model_validator(mode="after")
|
|
76
|
+
def validate_structure(self) -> "StreamPacket":
|
|
77
|
+
if self.op == StreamOpCode.ERROR:
|
|
78
|
+
if not isinstance(self.p, StreamError):
|
|
79
|
+
raise ValueError("Payload 'p' must be a valid StreamError when op is ERROR.")
|
|
80
|
+
|
|
81
|
+
if self.op == StreamOpCode.DELTA:
|
|
82
|
+
if not isinstance(self.p, str):
|
|
83
|
+
raise ValueError("Payload 'p' must be a string when op is DELTA.")
|
|
84
|
+
|
|
85
|
+
return self
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ServiceResponse(CoReasonBaseModel):
|
|
89
|
+
"""Synchronous response from an agent service."""
|
|
90
|
+
|
|
91
|
+
model_config = ConfigDict(frozen=True)
|
|
92
|
+
|
|
93
|
+
request_id: UUID
|
|
94
|
+
created_at: datetime
|
|
95
|
+
output: Dict[str, Any]
|
|
96
|
+
metrics: Optional[Dict[str, Any]] = None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class ServiceRequest(CoReasonBaseModel):
|
|
100
|
+
"""Request to an agent service.
|
|
101
|
+
|
|
102
|
+
Attributes:
|
|
103
|
+
request_id: Unique trace ID for the transaction.
|
|
104
|
+
context: Metadata about the request (User Identity, Auth, Session).
|
|
105
|
+
Separated from logic to enable consistent security policies.
|
|
106
|
+
payload: The actual arguments for the Agent's execution.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
model_config = ConfigDict(frozen=True)
|
|
110
|
+
|
|
111
|
+
request_id: UUID
|
|
112
|
+
# TODO: In v0.16.0, strictly type 'context' with a SessionContext model
|
|
113
|
+
# once the Identity primitive is fully integrated.
|
|
114
|
+
context: Dict[str, Any]
|
|
115
|
+
payload: Dict[str, Any]
|
|
@@ -0,0 +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
|
+
|
|
11
|
+
from loguru import logger
|
|
12
|
+
|
|
13
|
+
__all__ = ["logger"]
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/governance.py
RENAMED
|
@@ -41,6 +41,11 @@ def _risk_score(level: ToolRiskLevel) -> int:
|
|
|
41
41
|
def check_compliance_v2(manifest: ManifestV2, config: GovernanceConfig) -> ComplianceReport:
|
|
42
42
|
"""Enforce policy on V2 Manifest before compilation.
|
|
43
43
|
|
|
44
|
+
Validates:
|
|
45
|
+
- Tool risk levels against allowed maximums.
|
|
46
|
+
- Tool URIs against allowed domains.
|
|
47
|
+
- Presence of custom logic (LogicStep, complex SwitchStep) if restricted.
|
|
48
|
+
|
|
44
49
|
Args:
|
|
45
50
|
manifest: The V2 manifest to check.
|
|
46
51
|
config: The governance policy configuration.
|
|
@@ -57,9 +57,7 @@ class ReferenceResolver:
|
|
|
57
57
|
try:
|
|
58
58
|
target_path.relative_to(self.root_dir)
|
|
59
59
|
except ValueError:
|
|
60
|
-
raise ValueError(
|
|
61
|
-
f"Security Error: Reference '{ref_path}' escapes the root directory '{self.root_dir}'."
|
|
62
|
-
) from None
|
|
60
|
+
raise ValueError(f"Security Error: Reference '{ref_path}' escapes the root directory.") from None
|
|
63
61
|
|
|
64
62
|
if not target_path.exists():
|
|
65
63
|
raise FileNotFoundError(f"Referenced file not found: {target_path}")
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/contracts.py
RENAMED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
from typing import Any, Dict, Optional
|
|
2
2
|
|
|
3
|
-
from pydantic import
|
|
3
|
+
from pydantic import ConfigDict, Field
|
|
4
4
|
|
|
5
|
+
from coreason_manifest.common import CoReasonBaseModel
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
class InterfaceDefinition(CoReasonBaseModel):
|
|
7
9
|
"""Defines the input/output contract."""
|
|
8
10
|
|
|
9
|
-
model_config = ConfigDict(extra="forbid")
|
|
11
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
10
12
|
|
|
11
13
|
inputs: Dict[str, Any] = Field(default_factory=dict, description="JSON Schema definitions for arguments.")
|
|
12
14
|
outputs: Dict[str, Any] = Field(default_factory=dict, description="JSON Schema definitions for return values.")
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
class StateDefinition(
|
|
17
|
+
class StateDefinition(CoReasonBaseModel):
|
|
16
18
|
"""Defines the conversation memory/context structure."""
|
|
17
19
|
|
|
18
20
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -23,10 +25,10 @@ class StateDefinition(BaseModel):
|
|
|
23
25
|
backend: Optional[str] = Field(None, description="Backend storage type (e.g., 'redis', 'memory').")
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
class PolicyDefinition(
|
|
28
|
+
class PolicyDefinition(CoReasonBaseModel):
|
|
27
29
|
"""Defines execution policy and governance rules."""
|
|
28
30
|
|
|
29
|
-
model_config = ConfigDict(extra="forbid")
|
|
31
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
30
32
|
|
|
31
33
|
max_steps: Optional[int] = Field(None, description="Execution limit on number of steps.")
|
|
32
34
|
max_retries: int = Field(3, description="Maximum number of retries.")
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/definitions.py
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from typing import Annotated, Any, Dict, List, Literal, Optional, Union
|
|
2
2
|
|
|
3
|
-
from pydantic import
|
|
3
|
+
from pydantic import ConfigDict, Field
|
|
4
4
|
|
|
5
|
-
from coreason_manifest.common import StrictUri, ToolRiskLevel
|
|
5
|
+
from coreason_manifest.common import CoReasonBaseModel, StrictUri, ToolRiskLevel
|
|
6
6
|
from coreason_manifest.v2.spec.contracts import InterfaceDefinition, PolicyDefinition, StateDefinition
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class DesignMetadata(
|
|
9
|
+
class DesignMetadata(CoReasonBaseModel):
|
|
10
10
|
"""UI-specific metadata for the visual builder."""
|
|
11
11
|
|
|
12
12
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -20,7 +20,7 @@ class DesignMetadata(BaseModel):
|
|
|
20
20
|
collapsed: bool = Field(False, description="Whether the node is collapsed in UI.")
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class ToolDefinition(
|
|
23
|
+
class ToolDefinition(CoReasonBaseModel):
|
|
24
24
|
"""Definition of an external tool."""
|
|
25
25
|
|
|
26
26
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -33,7 +33,7 @@ class ToolDefinition(BaseModel):
|
|
|
33
33
|
description: Optional[str] = Field(None, description="Description of the tool.")
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class AgentDefinition(
|
|
36
|
+
class AgentDefinition(CoReasonBaseModel):
|
|
37
37
|
"""Definition of an Agent."""
|
|
38
38
|
|
|
39
39
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -49,13 +49,13 @@ class AgentDefinition(BaseModel):
|
|
|
49
49
|
knowledge: List[str] = Field(default_factory=list, description="List of file paths or knowledge base IDs.")
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
class GenericDefinition(
|
|
52
|
+
class GenericDefinition(CoReasonBaseModel):
|
|
53
53
|
"""Fallback for unknown definitions."""
|
|
54
54
|
|
|
55
55
|
model_config = ConfigDict(extra="allow")
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
class BaseStep(
|
|
58
|
+
class BaseStep(CoReasonBaseModel):
|
|
59
59
|
"""Base attributes for all steps."""
|
|
60
60
|
|
|
61
61
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -106,7 +106,7 @@ Step = Annotated[
|
|
|
106
106
|
]
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
class Workflow(
|
|
109
|
+
class Workflow(CoReasonBaseModel):
|
|
110
110
|
"""Defines the execution topology."""
|
|
111
111
|
|
|
112
112
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -115,7 +115,7 @@ class Workflow(BaseModel):
|
|
|
115
115
|
steps: Dict[str, Step] = Field(..., description="Dictionary of all steps indexed by ID.")
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
class ManifestMetadata(
|
|
118
|
+
class ManifestMetadata(CoReasonBaseModel):
|
|
119
119
|
"""Metadata for the manifest."""
|
|
120
120
|
|
|
121
121
|
model_config = ConfigDict(extra="allow", populate_by_name=True)
|
|
@@ -124,7 +124,7 @@ class ManifestMetadata(BaseModel):
|
|
|
124
124
|
design_metadata: Optional[DesignMetadata] = Field(None, alias="x-design", description="UI metadata.")
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
class ManifestV2(
|
|
127
|
+
class ManifestV2(CoReasonBaseModel):
|
|
128
128
|
"""Root object for Coreason Manifest V2."""
|
|
129
129
|
|
|
130
130
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -143,54 +143,3 @@ class ManifestV2(BaseModel):
|
|
|
143
143
|
],
|
|
144
144
|
] = Field(default_factory=dict, description="Reusable definitions.")
|
|
145
145
|
workflow: Workflow = Field(..., description="The main workflow topology.")
|
|
146
|
-
|
|
147
|
-
@model_validator(mode="after")
|
|
148
|
-
def validate_integrity(self) -> "ManifestV2":
|
|
149
|
-
"""Validate referential integrity of the manifest."""
|
|
150
|
-
steps = self.workflow.steps
|
|
151
|
-
|
|
152
|
-
# 1. Validate Start Step
|
|
153
|
-
if self.workflow.start not in steps:
|
|
154
|
-
raise ValueError(f"Start step '{self.workflow.start}' not found in steps.")
|
|
155
|
-
|
|
156
|
-
for step in steps.values():
|
|
157
|
-
# 2. Validate 'next' pointers (AgentStep, LogicStep, CouncilStep)
|
|
158
|
-
if hasattr(step, "next") and step.next:
|
|
159
|
-
if step.next not in steps:
|
|
160
|
-
raise ValueError(f"Step '{step.id}' references missing next step '{step.next}'.")
|
|
161
|
-
|
|
162
|
-
# 3. Validate SwitchStep targets
|
|
163
|
-
if isinstance(step, SwitchStep):
|
|
164
|
-
for target in step.cases.values():
|
|
165
|
-
if target not in steps:
|
|
166
|
-
raise ValueError(f"SwitchStep '{step.id}' references missing step '{target}' in cases.")
|
|
167
|
-
if step.default and step.default not in steps:
|
|
168
|
-
raise ValueError(f"SwitchStep '{step.id}' references missing step '{step.default}' in default.")
|
|
169
|
-
|
|
170
|
-
# 4. Validate Definition References
|
|
171
|
-
if isinstance(step, AgentStep):
|
|
172
|
-
if step.agent not in self.definitions:
|
|
173
|
-
raise ValueError(f"AgentStep '{step.id}' references missing agent '{step.agent}'.")
|
|
174
|
-
|
|
175
|
-
# Check type
|
|
176
|
-
agent_def = self.definitions[step.agent]
|
|
177
|
-
if not isinstance(agent_def, AgentDefinition):
|
|
178
|
-
raise ValueError(
|
|
179
|
-
f"AgentStep '{step.id}' references '{step.agent}' which is not an AgentDefinition "
|
|
180
|
-
f"(got {type(agent_def).__name__})."
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
if isinstance(step, CouncilStep):
|
|
184
|
-
for voter in step.voters:
|
|
185
|
-
if voter not in self.definitions:
|
|
186
|
-
raise ValueError(f"CouncilStep '{step.id}' references missing voter '{voter}'.")
|
|
187
|
-
|
|
188
|
-
# Check type
|
|
189
|
-
agent_def = self.definitions[voter]
|
|
190
|
-
if not isinstance(agent_def, AgentDefinition):
|
|
191
|
-
raise ValueError(
|
|
192
|
-
f"CouncilStep '{step.id}' references voter '{voter}' which is not an AgentDefinition "
|
|
193
|
-
f"(got {type(agent_def).__name__})."
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
return self
|
|
@@ -0,0 +1,195 @@
|
|
|
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
|
+
"""Validation logic for V2 Manifests."""
|
|
12
|
+
|
|
13
|
+
from typing import List
|
|
14
|
+
|
|
15
|
+
from coreason_manifest.v2.spec.definitions import (
|
|
16
|
+
AgentDefinition,
|
|
17
|
+
AgentStep,
|
|
18
|
+
CouncilStep,
|
|
19
|
+
ManifestV2,
|
|
20
|
+
SwitchStep,
|
|
21
|
+
ToolDefinition,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def validate_integrity(manifest: ManifestV2) -> ManifestV2:
|
|
26
|
+
"""Validate referential integrity of the manifest.
|
|
27
|
+
|
|
28
|
+
Checks:
|
|
29
|
+
1. workflow.start exists in steps.
|
|
30
|
+
2. step.next pointers exist in steps.
|
|
31
|
+
3. SwitchStep.cases targets exist.
|
|
32
|
+
4. agent references in AgentStep exist in definitions.
|
|
33
|
+
5. CouncilStep voters exist in definitions.
|
|
34
|
+
6. AgentDefinition tools exist in definitions.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
manifest: The V2 manifest to validate.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
The valid manifest (for chaining).
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
ValueError: If referential integrity is violated.
|
|
44
|
+
"""
|
|
45
|
+
steps = manifest.workflow.steps
|
|
46
|
+
|
|
47
|
+
# 1. Validate Start Step
|
|
48
|
+
if manifest.workflow.start not in steps:
|
|
49
|
+
raise ValueError(f"Start step '{manifest.workflow.start}' not found in steps.")
|
|
50
|
+
|
|
51
|
+
for step in steps.values():
|
|
52
|
+
# 2. Validate 'next' pointers (AgentStep, LogicStep, CouncilStep)
|
|
53
|
+
if hasattr(step, "next") and step.next:
|
|
54
|
+
if step.next not in steps:
|
|
55
|
+
raise ValueError(f"Step '{step.id}' references missing next step '{step.next}'.")
|
|
56
|
+
|
|
57
|
+
# 3. Validate SwitchStep targets
|
|
58
|
+
if isinstance(step, SwitchStep):
|
|
59
|
+
for target in step.cases.values():
|
|
60
|
+
if target not in steps:
|
|
61
|
+
raise ValueError(f"SwitchStep '{step.id}' references missing step '{target}' in cases.")
|
|
62
|
+
if step.default and step.default not in steps:
|
|
63
|
+
raise ValueError(f"SwitchStep '{step.id}' references missing step '{step.default}' in default.")
|
|
64
|
+
|
|
65
|
+
# 4. Validate Definition References
|
|
66
|
+
if isinstance(step, AgentStep):
|
|
67
|
+
if step.agent not in manifest.definitions:
|
|
68
|
+
raise ValueError(f"AgentStep '{step.id}' references missing agent '{step.agent}'.")
|
|
69
|
+
|
|
70
|
+
# Check type
|
|
71
|
+
agent_def = manifest.definitions[step.agent]
|
|
72
|
+
if not isinstance(agent_def, AgentDefinition):
|
|
73
|
+
raise ValueError(
|
|
74
|
+
f"AgentStep '{step.id}' references '{step.agent}' which is not an AgentDefinition "
|
|
75
|
+
f"(got {type(agent_def).__name__})."
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if isinstance(step, CouncilStep):
|
|
79
|
+
for voter in step.voters:
|
|
80
|
+
if voter not in manifest.definitions:
|
|
81
|
+
raise ValueError(f"CouncilStep '{step.id}' references missing voter '{voter}'.")
|
|
82
|
+
|
|
83
|
+
# Check type
|
|
84
|
+
agent_def = manifest.definitions[voter]
|
|
85
|
+
if not isinstance(agent_def, AgentDefinition):
|
|
86
|
+
raise ValueError(
|
|
87
|
+
f"CouncilStep '{step.id}' references voter '{voter}' which is not an AgentDefinition "
|
|
88
|
+
f"(got {type(agent_def).__name__})."
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# 5. Validate Agent Tools
|
|
92
|
+
for _, definition in manifest.definitions.items():
|
|
93
|
+
if isinstance(definition, AgentDefinition):
|
|
94
|
+
for tool_id in definition.tools:
|
|
95
|
+
if tool_id not in manifest.definitions:
|
|
96
|
+
raise ValueError(f"Agent '{definition.id}' references missing tool '{tool_id}'.")
|
|
97
|
+
|
|
98
|
+
tool_def = manifest.definitions[tool_id]
|
|
99
|
+
if not isinstance(tool_def, ToolDefinition):
|
|
100
|
+
raise ValueError(
|
|
101
|
+
f"Agent '{definition.id}' references '{tool_id}' which is not a ToolDefinition "
|
|
102
|
+
f"(got {type(tool_def).__name__})."
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
return manifest
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def validate_loose(manifest: ManifestV2) -> List[str]:
|
|
109
|
+
"""Validate "Draft" manifests for structural sanity only.
|
|
110
|
+
|
|
111
|
+
Checks:
|
|
112
|
+
- Unique Step IDs.
|
|
113
|
+
- SwitchStep case syntax (basic).
|
|
114
|
+
- Referential integrity (Start, Next, Switch, Agents, Tools) - warnings only.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
manifest: The V2 manifest to validate.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
List of warning messages (empty if clean).
|
|
121
|
+
"""
|
|
122
|
+
warnings: List[str] = []
|
|
123
|
+
|
|
124
|
+
# 1. Check unique Step IDs
|
|
125
|
+
for step_id, step in manifest.workflow.steps.items():
|
|
126
|
+
if step.id != step_id:
|
|
127
|
+
warnings.append(f"Step key '{step_id}' does not match step.id '{step.id}'.")
|
|
128
|
+
|
|
129
|
+
# 2. Check SwitchStep cases syntax
|
|
130
|
+
for step_id, step in manifest.workflow.steps.items():
|
|
131
|
+
if isinstance(step, SwitchStep):
|
|
132
|
+
for condition in step.cases.keys():
|
|
133
|
+
if not isinstance(condition, str) or not condition.strip():
|
|
134
|
+
warnings.append(f"SwitchStep '{step_id}' has invalid condition: {condition}")
|
|
135
|
+
|
|
136
|
+
# 3. Check Referential Integrity (Warnings)
|
|
137
|
+
steps = manifest.workflow.steps
|
|
138
|
+
|
|
139
|
+
# Start Step
|
|
140
|
+
if manifest.workflow.start not in steps:
|
|
141
|
+
warnings.append(f"Start step '{manifest.workflow.start}' not found in steps.")
|
|
142
|
+
|
|
143
|
+
for step in steps.values():
|
|
144
|
+
# 'next' pointers
|
|
145
|
+
if hasattr(step, "next") and step.next:
|
|
146
|
+
if step.next not in steps:
|
|
147
|
+
warnings.append(f"Step '{step.id}' references missing next step '{step.next}'.")
|
|
148
|
+
|
|
149
|
+
# SwitchStep targets
|
|
150
|
+
if isinstance(step, SwitchStep):
|
|
151
|
+
for target in step.cases.values():
|
|
152
|
+
if target not in steps:
|
|
153
|
+
warnings.append(f"SwitchStep '{step.id}' references missing step '{target}' in cases.")
|
|
154
|
+
if step.default and step.default not in steps:
|
|
155
|
+
warnings.append(f"SwitchStep '{step.id}' references missing step '{step.default}' in default.")
|
|
156
|
+
|
|
157
|
+
# Definition References
|
|
158
|
+
if isinstance(step, AgentStep):
|
|
159
|
+
if step.agent not in manifest.definitions:
|
|
160
|
+
warnings.append(f"AgentStep '{step.id}' references missing agent '{step.agent}'.")
|
|
161
|
+
else:
|
|
162
|
+
agent_def = manifest.definitions[step.agent]
|
|
163
|
+
if not isinstance(agent_def, AgentDefinition):
|
|
164
|
+
warnings.append(
|
|
165
|
+
f"AgentStep '{step.id}' references '{step.agent}' which is not an AgentDefinition "
|
|
166
|
+
f"(got {type(agent_def).__name__})."
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
if isinstance(step, CouncilStep):
|
|
170
|
+
for voter in step.voters:
|
|
171
|
+
if voter not in manifest.definitions:
|
|
172
|
+
warnings.append(f"CouncilStep '{step.id}' references missing voter '{voter}'.")
|
|
173
|
+
else:
|
|
174
|
+
agent_def = manifest.definitions[voter]
|
|
175
|
+
if not isinstance(agent_def, AgentDefinition):
|
|
176
|
+
warnings.append(
|
|
177
|
+
f"CouncilStep '{step.id}' references voter '{voter}' which is not an AgentDefinition "
|
|
178
|
+
f"(got {type(agent_def).__name__})."
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Agent Tools
|
|
182
|
+
for _, definition in manifest.definitions.items():
|
|
183
|
+
if isinstance(definition, AgentDefinition):
|
|
184
|
+
for tool_id in definition.tools:
|
|
185
|
+
if tool_id not in manifest.definitions:
|
|
186
|
+
warnings.append(f"Agent '{definition.id}' references missing tool '{tool_id}'.")
|
|
187
|
+
else:
|
|
188
|
+
tool_def = manifest.definitions[tool_id]
|
|
189
|
+
if not isinstance(tool_def, ToolDefinition):
|
|
190
|
+
warnings.append(
|
|
191
|
+
f"Agent '{definition.id}' references '{tool_id}' which is not a ToolDefinition "
|
|
192
|
+
f"(got {type(tool_def).__name__})."
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return warnings
|
|
@@ -1,51 +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 .v2.io import dump_to_yaml, load_from_yaml
|
|
12
|
-
from .v2.spec.contracts import InterfaceDefinition, PolicyDefinition, StateDefinition
|
|
13
|
-
from .v2.spec.definitions import (
|
|
14
|
-
AgentDefinition,
|
|
15
|
-
AgentStep,
|
|
16
|
-
CouncilStep,
|
|
17
|
-
LogicStep,
|
|
18
|
-
ManifestMetadata,
|
|
19
|
-
ManifestV2,
|
|
20
|
-
Step,
|
|
21
|
-
SwitchStep,
|
|
22
|
-
ToolDefinition,
|
|
23
|
-
Workflow,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
__version__ = "0.12.0"
|
|
27
|
-
|
|
28
|
-
Manifest = ManifestV2
|
|
29
|
-
Recipe = ManifestV2
|
|
30
|
-
load = load_from_yaml
|
|
31
|
-
dump = dump_to_yaml
|
|
32
|
-
|
|
33
|
-
__all__ = [
|
|
34
|
-
"Manifest",
|
|
35
|
-
"Recipe",
|
|
36
|
-
"load",
|
|
37
|
-
"dump",
|
|
38
|
-
"__version__",
|
|
39
|
-
"ManifestMetadata",
|
|
40
|
-
"AgentStep",
|
|
41
|
-
"Workflow",
|
|
42
|
-
"AgentDefinition",
|
|
43
|
-
"ToolDefinition",
|
|
44
|
-
"Step",
|
|
45
|
-
"LogicStep",
|
|
46
|
-
"SwitchStep",
|
|
47
|
-
"CouncilStep",
|
|
48
|
-
"InterfaceDefinition",
|
|
49
|
-
"StateDefinition",
|
|
50
|
-
"PolicyDefinition",
|
|
51
|
-
]
|
|
@@ -1,58 +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
|
-
# Copyright (c) 2025 CoReason, Inc.
|
|
12
|
-
#
|
|
13
|
-
# This software is proprietary and dual-licensed.
|
|
14
|
-
# Licensed under the Prosperity Public License 3.0 (the "License").
|
|
15
|
-
# A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
|
|
16
|
-
# For details, see the LICENSE file.
|
|
17
|
-
# Commercial use beyond a 30-day trial requires a separate license.
|
|
18
|
-
#
|
|
19
|
-
# Source Code: https://github.com/CoReason-AI/coreason_manifest
|
|
20
|
-
|
|
21
|
-
import os
|
|
22
|
-
import sys
|
|
23
|
-
from pathlib import Path
|
|
24
|
-
|
|
25
|
-
from loguru import logger
|
|
26
|
-
|
|
27
|
-
__all__ = ["logger"]
|
|
28
|
-
|
|
29
|
-
# Remove default handler
|
|
30
|
-
logger.remove()
|
|
31
|
-
|
|
32
|
-
# Sink 1: Stdout (Human-readable)
|
|
33
|
-
logger.add(
|
|
34
|
-
sys.stderr,
|
|
35
|
-
level="INFO",
|
|
36
|
-
format=(
|
|
37
|
-
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
|
|
38
|
-
"<level>{level: <8}</level> | "
|
|
39
|
-
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
|
|
40
|
-
"<level>{message}</level>"
|
|
41
|
-
),
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# Ensure logs directory exists
|
|
45
|
-
log_dir = os.getenv("COREASON_LOG_DIR", "logs")
|
|
46
|
-
log_path = Path(log_dir)
|
|
47
|
-
if not log_path.exists():
|
|
48
|
-
log_path.mkdir(parents=True, exist_ok=True)
|
|
49
|
-
|
|
50
|
-
# Sink 2: File (JSON, Rotation, Retention)
|
|
51
|
-
logger.add(
|
|
52
|
-
f"{log_dir}/app.log",
|
|
53
|
-
rotation="500 MB",
|
|
54
|
-
retention="10 days",
|
|
55
|
-
serialize=True,
|
|
56
|
-
enqueue=True,
|
|
57
|
-
level="INFO",
|
|
58
|
-
)
|
|
@@ -1,48 +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
|
-
"""Validation logic for V2 Manifests."""
|
|
12
|
-
|
|
13
|
-
from typing import List
|
|
14
|
-
|
|
15
|
-
from coreason_manifest.v2.spec.definitions import (
|
|
16
|
-
ManifestV2,
|
|
17
|
-
SwitchStep,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def validate_loose(manifest: ManifestV2) -> List[str]:
|
|
22
|
-
"""Validate "Draft" manifests for structural sanity only.
|
|
23
|
-
|
|
24
|
-
Checks:
|
|
25
|
-
- Unique Step IDs.
|
|
26
|
-
- SwitchStep case syntax (basic).
|
|
27
|
-
|
|
28
|
-
Args:
|
|
29
|
-
manifest: The V2 manifest to validate.
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
List of warning messages (empty if clean).
|
|
33
|
-
"""
|
|
34
|
-
warnings: List[str] = []
|
|
35
|
-
|
|
36
|
-
# 1. Check unique Step IDs
|
|
37
|
-
for step_id, step in manifest.workflow.steps.items():
|
|
38
|
-
if step.id != step_id:
|
|
39
|
-
warnings.append(f"Step key '{step_id}' does not match step.id '{step.id}'.")
|
|
40
|
-
|
|
41
|
-
# 2. Check SwitchStep cases
|
|
42
|
-
for step_id, step in manifest.workflow.steps.items():
|
|
43
|
-
if isinstance(step, SwitchStep):
|
|
44
|
-
for condition in step.cases.keys():
|
|
45
|
-
if not isinstance(condition, str) or not condition.strip():
|
|
46
|
-
warnings.append(f"SwitchStep '{step_id}' has invalid condition: {condition}")
|
|
47
|
-
|
|
48
|
-
return warnings
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/schemas/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coreason_manifest-0.12.0 → coreason_manifest-0.15.0}/src/coreason_manifest/v2/spec/__init__.py
RENAMED
|
File without changes
|