coreason-manifest 0.13.0__tar.gz → 0.16.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.13.0 → coreason_manifest-0.16.0}/PKG-INFO +3 -1
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/README.md +2 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/pyproject.toml +2 -2
- coreason_manifest-0.16.0/src/coreason_manifest/__init__.py +103 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/common.py +2 -2
- coreason_manifest-0.16.0/src/coreason_manifest/definitions/capabilities.py +28 -0
- coreason_manifest-0.16.0/src/coreason_manifest/definitions/identity.py +33 -0
- coreason_manifest-0.16.0/src/coreason_manifest/definitions/message.py +41 -0
- coreason_manifest-0.16.0/src/coreason_manifest/definitions/presentation.py +52 -0
- coreason_manifest-0.16.0/src/coreason_manifest/definitions/service.py +37 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/governance.py +2 -0
- coreason_manifest-0.16.0/src/coreason_manifest/spec/cap.py +115 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/governance.py +5 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/resolver.py +1 -3
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/spec/contracts.py +8 -6
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/spec/definitions.py +14 -61
- coreason_manifest-0.16.0/src/coreason_manifest/v2/validator.py +195 -0
- coreason_manifest-0.13.0/src/coreason_manifest/__init__.py +0 -51
- coreason_manifest-0.13.0/src/coreason_manifest/v2/validator.py +0 -48
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/LICENSE +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/NOTICE +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/schemas/__init__.py +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/schemas/coreason-v2.schema.json +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/utils/__init__.py +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/utils/logger.py +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/__init__.py +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/io.py +0 -0
- {coreason_manifest-0.13.0 → coreason_manifest-0.16.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.16.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
|
|
|
@@ -168,6 +168,8 @@ For full details, see the [Usage Documentation](docs/usage.md).
|
|
|
168
168
|
|
|
169
169
|
## Documentation
|
|
170
170
|
|
|
171
|
+
**[Full Documentation Index](docs/index.md)**
|
|
172
|
+
|
|
171
173
|
* [Usage Guide](docs/usage.md): How to load and create manifests.
|
|
172
174
|
* [Governance & Policy Enforcement](docs/governance_policy_enforcement.md): Validating agents against organizational rules.
|
|
173
175
|
* [Coreason Agent Manifest (CAM)](docs/cap/specification.md): The Canonical YAML Authoring Format.
|
|
@@ -90,6 +90,8 @@ For full details, see the [Usage Documentation](docs/usage.md).
|
|
|
90
90
|
|
|
91
91
|
## Documentation
|
|
92
92
|
|
|
93
|
+
**[Full Documentation Index](docs/index.md)**
|
|
94
|
+
|
|
93
95
|
* [Usage Guide](docs/usage.md): How to load and create manifests.
|
|
94
96
|
* [Governance & Policy Enforcement](docs/governance_policy_enforcement.md): Validating agents against organizational rules.
|
|
95
97
|
* [Coreason Agent Manifest (CAM)](docs/cap/specification.md): The Canonical YAML Authoring Format.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "coreason_manifest"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.16.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"
|
|
@@ -32,7 +32,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
32
32
|
|
|
33
33
|
[project]
|
|
34
34
|
name = "coreason_manifest"
|
|
35
|
-
version = "0.
|
|
35
|
+
version = "0.16.0"
|
|
36
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."
|
|
37
37
|
readme = "README.md"
|
|
38
38
|
requires-python = ">=3.12"
|
|
@@ -0,0 +1,103 @@
|
|
|
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.capabilities import AgentCapabilities, DeliveryMode
|
|
13
|
+
from .definitions.identity import Identity
|
|
14
|
+
from .definitions.message import ChatMessage, Role
|
|
15
|
+
from .definitions.presentation import (
|
|
16
|
+
AnyPresentationEvent,
|
|
17
|
+
ArtifactEvent,
|
|
18
|
+
CitationEvent,
|
|
19
|
+
PresentationEvent,
|
|
20
|
+
PresentationEventType,
|
|
21
|
+
)
|
|
22
|
+
from .definitions.service import AgentRequest, ServiceContract
|
|
23
|
+
from .governance import ComplianceReport, ComplianceViolation, GovernanceConfig
|
|
24
|
+
from .spec.cap import (
|
|
25
|
+
ErrorSeverity,
|
|
26
|
+
HealthCheckResponse,
|
|
27
|
+
HealthCheckStatus,
|
|
28
|
+
ServiceRequest,
|
|
29
|
+
ServiceResponse,
|
|
30
|
+
StreamError,
|
|
31
|
+
StreamOpCode,
|
|
32
|
+
StreamPacket,
|
|
33
|
+
)
|
|
34
|
+
from .v2.governance import check_compliance_v2
|
|
35
|
+
from .v2.io import dump_to_yaml, load_from_yaml
|
|
36
|
+
from .v2.spec.contracts import InterfaceDefinition, PolicyDefinition, StateDefinition
|
|
37
|
+
from .v2.spec.definitions import (
|
|
38
|
+
AgentDefinition,
|
|
39
|
+
AgentStep,
|
|
40
|
+
CouncilStep,
|
|
41
|
+
LogicStep,
|
|
42
|
+
ManifestMetadata,
|
|
43
|
+
ManifestV2,
|
|
44
|
+
Step,
|
|
45
|
+
SwitchStep,
|
|
46
|
+
ToolDefinition,
|
|
47
|
+
Workflow,
|
|
48
|
+
)
|
|
49
|
+
from .v2.validator import validate_integrity, validate_loose
|
|
50
|
+
|
|
51
|
+
__version__ = "0.15.0"
|
|
52
|
+
|
|
53
|
+
Manifest = ManifestV2
|
|
54
|
+
Recipe = ManifestV2
|
|
55
|
+
load = load_from_yaml
|
|
56
|
+
dump = dump_to_yaml
|
|
57
|
+
|
|
58
|
+
__all__ = [
|
|
59
|
+
"Manifest",
|
|
60
|
+
"Recipe",
|
|
61
|
+
"load",
|
|
62
|
+
"dump",
|
|
63
|
+
"__version__",
|
|
64
|
+
"ManifestMetadata",
|
|
65
|
+
"AgentStep",
|
|
66
|
+
"Workflow",
|
|
67
|
+
"AgentDefinition",
|
|
68
|
+
"ToolDefinition",
|
|
69
|
+
"Step",
|
|
70
|
+
"LogicStep",
|
|
71
|
+
"SwitchStep",
|
|
72
|
+
"CouncilStep",
|
|
73
|
+
"InterfaceDefinition",
|
|
74
|
+
"StateDefinition",
|
|
75
|
+
"PolicyDefinition",
|
|
76
|
+
"ToolRiskLevel",
|
|
77
|
+
"AgentCapabilities",
|
|
78
|
+
"DeliveryMode",
|
|
79
|
+
"GovernanceConfig",
|
|
80
|
+
"ComplianceReport",
|
|
81
|
+
"ComplianceViolation",
|
|
82
|
+
"Identity",
|
|
83
|
+
"Role",
|
|
84
|
+
"ChatMessage",
|
|
85
|
+
"PresentationEventType",
|
|
86
|
+
"PresentationEvent",
|
|
87
|
+
"AnyPresentationEvent",
|
|
88
|
+
"CitationEvent",
|
|
89
|
+
"ArtifactEvent",
|
|
90
|
+
"HealthCheckResponse",
|
|
91
|
+
"HealthCheckStatus",
|
|
92
|
+
"ServiceRequest",
|
|
93
|
+
"ServiceResponse",
|
|
94
|
+
"StreamPacket",
|
|
95
|
+
"StreamError",
|
|
96
|
+
"StreamOpCode",
|
|
97
|
+
"ErrorSeverity",
|
|
98
|
+
"validate_integrity",
|
|
99
|
+
"validate_loose",
|
|
100
|
+
"check_compliance_v2",
|
|
101
|
+
"AgentRequest",
|
|
102
|
+
"ServiceContract",
|
|
103
|
+
]
|
|
@@ -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,28 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from pydantic import ConfigDict, Field
|
|
5
|
+
|
|
6
|
+
from ..common import CoReasonBaseModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DeliveryMode(str, Enum):
|
|
10
|
+
"""Supported transport mechanisms."""
|
|
11
|
+
|
|
12
|
+
REQUEST_RESPONSE = "request_response"
|
|
13
|
+
SSE = "sse"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AgentCapabilities(CoReasonBaseModel):
|
|
17
|
+
"""Feature flags and capabilities for the agent."""
|
|
18
|
+
|
|
19
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
20
|
+
|
|
21
|
+
delivery_mode: List[DeliveryMode] = Field(
|
|
22
|
+
default_factory=lambda: [DeliveryMode.SSE],
|
|
23
|
+
description="Supported transport mechanisms.",
|
|
24
|
+
)
|
|
25
|
+
history_support: bool = Field(
|
|
26
|
+
default=True,
|
|
27
|
+
description="Whether the agent supports conversation history/context.",
|
|
28
|
+
)
|
|
@@ -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]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import ConfigDict
|
|
4
|
+
|
|
5
|
+
from ..common import CoReasonBaseModel
|
|
6
|
+
from ..spec.cap import ServiceRequest, ServiceResponse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AgentRequest(CoReasonBaseModel):
|
|
10
|
+
"""Strictly typed payload inside a ServiceRequest."""
|
|
11
|
+
|
|
12
|
+
model_config = ConfigDict(frozen=True)
|
|
13
|
+
|
|
14
|
+
query: str
|
|
15
|
+
files: List[str] = []
|
|
16
|
+
conversation_id: Optional[str] = None
|
|
17
|
+
meta: Dict[str, Any] = {}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ServiceContract:
|
|
21
|
+
"""Utility class to generate the OpenAPI specification."""
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def generate_openapi() -> Dict[str, Any]:
|
|
25
|
+
"""Generate the OpenAPI 3.1 Path Item Object for the agent service."""
|
|
26
|
+
return {
|
|
27
|
+
"post": {
|
|
28
|
+
"summary": "Invoke Agent",
|
|
29
|
+
"requestBody": {"content": {"application/json": {"schema": ServiceRequest.model_json_schema()}}},
|
|
30
|
+
"responses": {
|
|
31
|
+
"200": {
|
|
32
|
+
"description": "Successful Response",
|
|
33
|
+
"content": {"application/json": {"schema": ServiceResponse.model_json_schema()}},
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -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]
|
{coreason_manifest-0.13.0 → coreason_manifest-0.16.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.13.0 → coreason_manifest-0.16.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.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/spec/definitions.py
RENAMED
|
@@ -1,12 +1,13 @@
|
|
|
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
|
+
from coreason_manifest.definitions.capabilities import AgentCapabilities
|
|
6
7
|
from coreason_manifest.v2.spec.contracts import InterfaceDefinition, PolicyDefinition, StateDefinition
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class DesignMetadata(
|
|
10
|
+
class DesignMetadata(CoReasonBaseModel):
|
|
10
11
|
"""UI-specific metadata for the visual builder."""
|
|
11
12
|
|
|
12
13
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -20,7 +21,7 @@ class DesignMetadata(BaseModel):
|
|
|
20
21
|
collapsed: bool = Field(False, description="Whether the node is collapsed in UI.")
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
class ToolDefinition(
|
|
24
|
+
class ToolDefinition(CoReasonBaseModel):
|
|
24
25
|
"""Definition of an external tool."""
|
|
25
26
|
|
|
26
27
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -33,7 +34,7 @@ class ToolDefinition(BaseModel):
|
|
|
33
34
|
description: Optional[str] = Field(None, description="Description of the tool.")
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
class AgentDefinition(
|
|
37
|
+
class AgentDefinition(CoReasonBaseModel):
|
|
37
38
|
"""Definition of an Agent."""
|
|
38
39
|
|
|
39
40
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -47,15 +48,18 @@ class AgentDefinition(BaseModel):
|
|
|
47
48
|
model: Optional[str] = Field(None, description="LLM identifier.")
|
|
48
49
|
tools: List[str] = Field(default_factory=list, description="List of Tool IDs or URI references.")
|
|
49
50
|
knowledge: List[str] = Field(default_factory=list, description="List of file paths or knowledge base IDs.")
|
|
51
|
+
capabilities: AgentCapabilities = Field(
|
|
52
|
+
default_factory=AgentCapabilities, description="Feature flags and capabilities for the agent."
|
|
53
|
+
)
|
|
50
54
|
|
|
51
55
|
|
|
52
|
-
class GenericDefinition(
|
|
56
|
+
class GenericDefinition(CoReasonBaseModel):
|
|
53
57
|
"""Fallback for unknown definitions."""
|
|
54
58
|
|
|
55
59
|
model_config = ConfigDict(extra="allow")
|
|
56
60
|
|
|
57
61
|
|
|
58
|
-
class BaseStep(
|
|
62
|
+
class BaseStep(CoReasonBaseModel):
|
|
59
63
|
"""Base attributes for all steps."""
|
|
60
64
|
|
|
61
65
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -106,7 +110,7 @@ Step = Annotated[
|
|
|
106
110
|
]
|
|
107
111
|
|
|
108
112
|
|
|
109
|
-
class Workflow(
|
|
113
|
+
class Workflow(CoReasonBaseModel):
|
|
110
114
|
"""Defines the execution topology."""
|
|
111
115
|
|
|
112
116
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -115,7 +119,7 @@ class Workflow(BaseModel):
|
|
|
115
119
|
steps: Dict[str, Step] = Field(..., description="Dictionary of all steps indexed by ID.")
|
|
116
120
|
|
|
117
121
|
|
|
118
|
-
class ManifestMetadata(
|
|
122
|
+
class ManifestMetadata(CoReasonBaseModel):
|
|
119
123
|
"""Metadata for the manifest."""
|
|
120
124
|
|
|
121
125
|
model_config = ConfigDict(extra="allow", populate_by_name=True)
|
|
@@ -124,7 +128,7 @@ class ManifestMetadata(BaseModel):
|
|
|
124
128
|
design_metadata: Optional[DesignMetadata] = Field(None, alias="x-design", description="UI metadata.")
|
|
125
129
|
|
|
126
130
|
|
|
127
|
-
class ManifestV2(
|
|
131
|
+
class ManifestV2(CoReasonBaseModel):
|
|
128
132
|
"""Root object for Coreason Manifest V2."""
|
|
129
133
|
|
|
130
134
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
@@ -143,54 +147,3 @@ class ManifestV2(BaseModel):
|
|
|
143
147
|
],
|
|
144
148
|
] = Field(default_factory=dict, description="Reusable definitions.")
|
|
145
149
|
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.13.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,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
|
{coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/schemas/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coreason_manifest-0.13.0 → coreason_manifest-0.16.0}/src/coreason_manifest/v2/spec/__init__.py
RENAMED
|
File without changes
|