Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/omnibase_core/enums/enum_core_error_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ class EnumCoreErrorCode(EnumOnexErrorCode):
NODE_EXECUTION_ERROR = "ONEX_CORE_273_NODE_EXECUTION_ERROR"
UNSUPPORTED_CAPABILITY_ERROR = "ONEX_CORE_274_UNSUPPORTED_CAPABILITY_ERROR"

# Workflow execution limit errors (281-290)
WORKFLOW_STEP_LIMIT_EXCEEDED = "ONEX_CORE_281_WORKFLOW_STEP_LIMIT_EXCEEDED"
WORKFLOW_PAYLOAD_SIZE_EXCEEDED = "ONEX_CORE_282_WORKFLOW_PAYLOAD_SIZE_EXCEEDED"
WORKFLOW_TOTAL_PAYLOAD_EXCEEDED = "ONEX_CORE_283_WORKFLOW_TOTAL_PAYLOAD_EXCEEDED"

def get_component(self) -> str:
"""Get the component identifier for this error code."""
return "CORE"
Expand Down Expand Up @@ -258,6 +263,10 @@ def get_exit_code(self) -> int:
EnumCoreErrorCode.PURITY_VIOLATION_ERROR: EnumCLIExitCode.ERROR,
EnumCoreErrorCode.NODE_EXECUTION_ERROR: EnumCLIExitCode.ERROR,
EnumCoreErrorCode.UNSUPPORTED_CAPABILITY_ERROR: EnumCLIExitCode.ERROR,
# Workflow execution limit errors -> ERROR
EnumCoreErrorCode.WORKFLOW_STEP_LIMIT_EXCEEDED: EnumCLIExitCode.ERROR,
EnumCoreErrorCode.WORKFLOW_PAYLOAD_SIZE_EXCEEDED: EnumCLIExitCode.ERROR,
EnumCoreErrorCode.WORKFLOW_TOTAL_PAYLOAD_EXCEEDED: EnumCLIExitCode.ERROR,
}


Expand Down Expand Up @@ -375,5 +384,8 @@ def get_core_error_description(error_code: EnumCoreErrorCode) -> str:
EnumCoreErrorCode.PURITY_VIOLATION_ERROR: "Purity violation in pure node",
EnumCoreErrorCode.NODE_EXECUTION_ERROR: "Node execution failed",
EnumCoreErrorCode.UNSUPPORTED_CAPABILITY_ERROR: "Unsupported capability requested",
EnumCoreErrorCode.WORKFLOW_STEP_LIMIT_EXCEEDED: "Workflow step count exceeds maximum limit",
EnumCoreErrorCode.WORKFLOW_PAYLOAD_SIZE_EXCEEDED: "Workflow step payload size exceeds maximum limit",
EnumCoreErrorCode.WORKFLOW_TOTAL_PAYLOAD_EXCEEDED: "Workflow total payload size exceeds maximum limit",
}
return descriptions.get(error_code, "Unknown error")
10 changes: 9 additions & 1 deletion src/omnibase_core/infrastructure/node_config_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from omnibase_core.models.configuration.model_node_config_value import (
ConfigValue,
ModelNodeConfigSchema,
is_valid_value_type,
)


Expand Down Expand Up @@ -266,9 +267,16 @@ async def get_config_schema(self) -> dict[str, ModelNodeConfigSchema]:
"""
schema: dict[str, ModelNodeConfigSchema] = {}
for key, value in self._DEFAULTS.items():
type_name = type(value).__name__
# Type guard validates and narrows type_name to VALID_VALUE_TYPES
if not is_valid_value_type(type_name):
raise ValueError( # error-ok: internal bootstrap validation before OnexError available
f"Invalid config type '{type_name}' for key '{key}'. "
f"Allowed types: ('int', 'float', 'bool', 'str')"
)
schema[key] = ModelNodeConfigSchema(
key=key,
type=type(value).__name__,
type=type_name,
default=value,
)
return schema
14 changes: 14 additions & 0 deletions src/omnibase_core/models/configuration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,32 @@
ModelTierConfig,
)
from .model_compute_cache_config import ModelComputeCacheConfig
from .model_git_hub_comment_change import ModelGitHubCommentChange
from .model_git_hub_issue_comment_changes import ModelGitHubIssueCommentChanges
from .model_git_hub_issue_comment_event import ModelGitHubIssueCommentEvent
from .model_node_config_entry import ConfigValue, ModelNodeConfigEntry
from .model_node_config_value import ModelNodeConfigSchema
from .model_priority_metadata import ModelPriorityMetadata
from .model_priority_metadata_summary import ModelPriorityMetadataSummary
from .model_throttle_response import ModelThrottleResponse
from .model_throttling_behavior import ModelThrottlingBehavior

__all__ = [
"ConfigValue",
"ModelAPIConfig",
"ModelCLIConfig",
"ModelComputeCacheConfig",
"ModelDatabaseConfig",
"ModelGitHubCommentChange",
"ModelGitHubIssueCommentChanges",
"ModelGitHubIssueCommentEvent",
"ModelMonitoringConfig",
"ModelNodeConfigEntry",
"ModelNodeConfigSchema",
"ModelOutputConfig",
"ModelPriorityMetadata",
"ModelPriorityMetadataSummary",
"ModelThrottleResponse",
"ModelThrottlingBehavior",
"ModelTierConfig",
]
57 changes: 57 additions & 0 deletions src/omnibase_core/models/configuration/model_config_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Common types for configuration models."""

from typing import Literal, TypeGuard

# Type alias for valid configuration value types
ConfigValue = int | float | bool | str

# Literal type constraining value_type/config_type to valid values
VALID_VALUE_TYPES = Literal["int", "float", "bool", "str"]

# Tuple of valid type names for runtime checking
_VALID_TYPE_NAMES: tuple[str, ...] = ("int", "float", "bool", "str")


def is_valid_value_type(type_name: str) -> TypeGuard[VALID_VALUE_TYPES]:
"""Type guard to check if a string is a valid value type.

This function narrows the type of type_name from str to VALID_VALUE_TYPES
when it returns True, enabling mypy to understand the type refinement.

Args:
type_name: The type name string to validate.

Returns:
True if type_name is one of 'int', 'float', 'bool', 'str'.
"""
return type_name in _VALID_TYPE_NAMES


def validate_config_value_type(
value_type: VALID_VALUE_TYPES, default: ConfigValue
) -> None:
"""Validate that default value matches declared type.

Args:
value_type: The declared type ('int', 'float', 'bool', 'str')
default: The default value to validate

Raises:
ValueError: If default value doesn't match declared type
"""
type_map: dict[str, type | tuple[type, ...]] = {
"int": int,
"float": (int, float), # int is valid for float
"bool": bool,
"str": str,
}
expected = type_map[value_type]
# Strict bool check - don't allow int/float to match bool
if value_type == "bool" and not isinstance(default, bool):
raise ValueError( # error-ok: Pydantic validator requires ValueError
f"default must be bool, got {type(default).__name__}"
)
if not isinstance(default, expected):
raise ValueError( # error-ok: Pydantic validator requires ValueError
f"default must be {value_type}, got {type(default).__name__}"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""ModelGitHubCommentChange model."""

from pydantic import BaseModel, Field


class ModelGitHubCommentChange(BaseModel):
"""Represents a change to a GitHub comment field."""

from_: str | None = Field(default=None, alias="from", description="Previous value")
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""ModelGitHubIssueCommentChanges model."""

from pydantic import BaseModel, Field

from .model_git_hub_comment_change import ModelGitHubCommentChange


class ModelGitHubIssueCommentChanges(BaseModel):
"""Changes made to a GitHub issue comment (for edited action)."""

body: ModelGitHubCommentChange | None = Field(
default=None, description="Body content change"
)
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
from pydantic import Field
"""GitHubIssueCommentEvent model."""

"""
GitHubIssueCommentEvent model.
"""

from pydantic import BaseModel
from pydantic import BaseModel, Field

from .model_git_hub_comment_change import ModelGitHubCommentChange
from .model_git_hub_issue import ModelGitHubIssue
from .model_git_hub_issue_comment import ModelGitHubIssueComment
from .model_git_hub_issue_comment_changes import ModelGitHubIssueCommentChanges
from .model_git_hub_repository import ModelGitHubRepository
from .model_git_hub_user import ModelGitHubUser


class ModelGitHubCommentChange(BaseModel):
"""Represents a change to a GitHub comment field."""

from_: str | None = Field(default=None, alias="from", description="Previous value")


class ModelGitHubIssueCommentChanges(BaseModel):
"""Changes made to a GitHub issue comment (for edited action)."""

body: ModelGitHubCommentChange | None = Field(
default=None, description="Body content change"
)
__all__ = [
"ModelGitHubCommentChange",
"ModelGitHubIssueCommentChanges",
"ModelGitHubIssueCommentEvent",
]
Comment on lines +12 to +16

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find imports of these classes from model_git_hub_issue_comment_event module
echo "=== Checking for imports from model_git_hub_issue_comment_event ==="
rg -n "from.*model_git_hub_issue_comment_event.*import" --type py

echo ""
echo "=== Checking for direct module references ==="
rg -n "model_git_hub_issue_comment_event\.(ModelGitHubCommentChange|ModelGitHubIssueCommentChanges)" --type py

echo ""
echo "=== Checking __init__.py file content ==="
cat -n src/omnibase_core/models/configuration/__init__.py

Repository: OmniNode-ai/omnibase_core

Length of output: 1935


Remove unnecessary re-exports from __all__.

The __all__ list in this file re-exports ModelGitHubCommentChange and ModelGitHubIssueCommentChanges, but these classes are never imported from this module. All code imports these classes directly from their source modules (model_git_hub_comment_change and model_git_hub_issue_comment_changes), and the package __init__.py already handles their public API exposure. Keep only ModelGitHubIssueCommentEvent in __all__.

🤖 Prompt for AI Agents
In src/omnibase_core/models/configuration/model_git_hub_issue_comment_event.py
around lines 12 to 16, the __all__ list incorrectly re-exports
ModelGitHubCommentChange and ModelGitHubIssueCommentChanges which are not
imported here; remove those two names so __all__ only contains
"ModelGitHubIssueCommentEvent" to reflect the actual exports and avoid
misleading re-exports.



class ModelGitHubIssueCommentEvent(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Model for node configuration entry."""

from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, model_validator

# Type alias for valid configuration value types
# IMPORTANT: bool MUST come before int because bool is a subclass of int in Python
# If int comes first, Pydantic will match True/False as 1/0 integers
ConfigValue = bool | int | float | str
from omnibase_core.models.configuration.model_config_types import (
VALID_VALUE_TYPES,
ConfigValue,
validate_config_value_type,
)


class ModelNodeConfigEntry(BaseModel):
Expand All @@ -25,7 +26,7 @@ class ModelNodeConfigEntry(BaseModel):
...,
description="Configuration key (e.g., 'compute.max_parallel_workers')",
)
value_type: str = Field(
value_type: VALID_VALUE_TYPES = Field(
...,
description="Type name of the value ('int', 'float', 'bool', 'str')",
)
Expand All @@ -35,3 +36,9 @@ class ModelNodeConfigEntry(BaseModel):
)

model_config = {"frozen": True}

@model_validator(mode="after")
def validate_default_type(self) -> "ModelNodeConfigEntry":
"""Ensure default value type matches declared value_type."""
validate_config_value_type(self.value_type, self.default)
return self
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Model for node configuration schema."""

from pydantic import BaseModel, Field, model_validator

from omnibase_core.models.configuration.model_config_types import (
VALID_VALUE_TYPES,
ConfigValue,
validate_config_value_type,
)


class ModelNodeConfigSchema(BaseModel):
"""
Strongly-typed model for node configuration schema.

Represents a complete configuration schema entry including
key, type, and default value information.

Attributes:
key: Configuration key
config_type: Type name of the value ('int', 'float', 'bool', 'str')
default: Default value
"""

key: str = Field(..., description="Configuration key")
config_type: VALID_VALUE_TYPES = Field(
..., alias="type", description="Type name of the value"
)
default: ConfigValue = Field(..., description="Default value")

model_config = {"frozen": True, "populate_by_name": True}

@model_validator(mode="after")
def validate_default_type(self) -> "ModelNodeConfigSchema":
"""Ensure default value type matches declared config_type."""
validate_config_value_type(self.config_type, self.default)
return self
43 changes: 18 additions & 25 deletions src/omnibase_core/models/configuration/model_node_config_value.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
"""Model for node configuration schema."""
"""Model for node configuration values - re-exports from split files."""

from pydantic import BaseModel, Field

from omnibase_core.models.configuration.model_node_config_entry import (
from omnibase_core.models.configuration.model_config_types import (
VALID_VALUE_TYPES,
ConfigValue,
is_valid_value_type,
validate_config_value_type,
)
from omnibase_core.models.configuration.model_node_config_entry import (
ModelNodeConfigEntry,
)
from omnibase_core.models.configuration.model_node_config_schema import (
ModelNodeConfigSchema,
)

__all__ = ["ConfigValue", "ModelNodeConfigEntry", "ModelNodeConfigSchema"]


class ModelNodeConfigSchema(BaseModel):
"""
Strongly-typed model for node configuration schema.

Represents a complete configuration schema entry including
key, type, and default value information.

Attributes:
key: Configuration key
type: Type name of the value
default: Default value
"""

key: str = Field(..., description="Configuration key")
type: str = Field(..., description="Type name of the value")
default: ConfigValue = Field(..., description="Default value")

model_config = {"frozen": True}
__all__ = [
"ConfigValue",
"ModelNodeConfigEntry",
"ModelNodeConfigSchema",
"VALID_VALUE_TYPES",
"is_valid_value_type",
"validate_config_value_type",
]
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,12 @@
from omnibase_core.models.configuration.model_notification_settings import (
ModelNotificationSettings,
)
from omnibase_core.models.configuration.model_priority_metadata_summary import (
ModelPriorityMetadataSummary,
)
from omnibase_core.models.errors.model_onex_error import ModelOnexError


class ModelPriorityMetadataSummary(BaseModel):
"""Summary of priority metadata."""

owner: str | None = Field(default=None, description="Owner of the priority")
approval_required: bool = Field(
default=False, description="Whether approval is required"
)
approved_users_count: int = Field(default=0, description="Number of approved users")
approved_groups_count: int = Field(
default=0, description="Number of approved groups"
)
tags_count: int = Field(default=0, description="Number of tags")
has_sla: bool = Field(default=False, description="Whether SLA is defined")
has_cost: bool = Field(default=False, description="Whether cost is defined")
has_usage_limit: bool = Field(
default=False, description="Whether usage limit is defined"
)
age_days: float = Field(default=0.0, description="Age in days since creation")
__all__ = ["ModelPriorityMetadata", "ModelPriorityMetadataSummary"]


class ModelPriorityMetadata(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""ONEX-compatible Priority Metadata Summary Model.

Summary model for priority metadata with ONEX compliance.
"""

from pydantic import BaseModel, Field


class ModelPriorityMetadataSummary(BaseModel):
"""Summary of priority metadata."""

owner: str | None = Field(default=None, description="Owner of the priority")
approval_required: bool = Field(
default=False, description="Whether approval is required"
)
approved_users_count: int = Field(default=0, description="Number of approved users")
approved_groups_count: int = Field(
default=0, description="Number of approved groups"
)
tags_count: int = Field(default=0, description="Number of tags")
has_sla: bool = Field(default=False, description="Whether SLA is defined")
has_cost: bool = Field(default=False, description="Whether cost is defined")
has_usage_limit: bool = Field(
default=False, description="Whether usage limit is defined"
)
age_days: float = Field(default=0.0, description="Age in days since creation")
Loading