Repository navigation
feat(replay): add configuration override injection for A/B testing (OMN-1205) #331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jonahgabriel
merged 7 commits into
main
from
jonah/omn-1205-demo-configuration-override-injection
Jan 5, 2026
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
40512aa
feat(replay): add configuration override injection for A/B testing (O…
jonahgabriel 3b2948c
refactor(replay): relocate non-node utilities from pipeline to services
jonahgabriel 75d86c6
fix(validation): add architectural exemption for replay infrastructure
jonahgabriel 9334793
merge: resolve conflict in validate_naming.py architectural exemptions
jonahgabriel 5d3cd55
fix(replay): fix test imports and add __all__ exports (OMN-1205)
jonahgabriel 152bbf0
merge: resolve conflict in replay models __init__.py
jonahgabriel 3ca288d
fix(replay): address PR #331 review feedback
jonahgabriel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/omnibase_core/enums/replay/enum_override_injection_point.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # SPDX-FileCopyrightText: 2025 OmniNode Team <info@omninode.ai> | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| """EnumOverrideInjectionPoint - Injection points for config overrides. | ||
|
|
||
| Defines where configuration overrides can be applied during replay execution. | ||
| This is a CLOSED vocabulary - new injection points require explicit addition. | ||
|
|
||
| .. versionadded:: 0.4.0 | ||
| Added Configuration Override Injection (OMN-1205) | ||
| """ | ||
|
|
||
| from enum import Enum | ||
|
|
||
|
|
||
| class EnumOverrideInjectionPoint(str, Enum): | ||
| """Injection points for configuration overrides during replay. | ||
|
|
||
| Defines WHERE configuration overrides can be applied during replay | ||
| execution. This is a closed vocabulary - new injection points require | ||
| explicit addition. | ||
|
|
||
| - **HANDLER_CONFIG**: Patch handler configuration model (pre-execution). | ||
| Applied before handler execution begins. | ||
|
|
||
| - **ENVIRONMENT**: Environment variable overlay (NOT os.environ mutation). | ||
| Provides isolated environment context without affecting global state. | ||
|
|
||
| - **CONTEXT**: Patch replay context fields (copy only, not original). | ||
| Modifies a copy of the context to avoid side effects. | ||
|
|
||
| Thread Safety: | ||
| Enum values are immutable and thread-safe. | ||
|
|
||
| Example: | ||
| >>> point = EnumOverrideInjectionPoint.HANDLER_CONFIG | ||
| >>> point == "handler_config" | ||
| True | ||
| >>> EnumOverrideInjectionPoint("environment") | ||
| <EnumOverrideInjectionPoint.ENVIRONMENT: 'environment'> | ||
|
|
||
| .. versionadded:: 0.4.0 | ||
| """ | ||
|
|
||
| HANDLER_CONFIG = "handler_config" | ||
| """Patch handler configuration model (pre-execution).""" | ||
|
|
||
| ENVIRONMENT = "environment" | ||
| """Environment variable overlay (NOT os.environ mutation).""" | ||
|
|
||
| CONTEXT = "context" | ||
| """Patch replay context fields (copy only, not original).""" | ||
|
|
||
|
|
||
| __all__ = ["EnumOverrideInjectionPoint"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # SPDX-FileCopyrightText: 2025 OmniNode Team <info@omninode.ai> | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| """ | ||
| Single configuration override specification for replay injection. | ||
|
|
||
| .. versionadded:: 0.4.0 | ||
| Added Configuration Override Injection (OMN-1205) | ||
| """ | ||
|
|
||
| from typing import Any | ||
|
|
||
| from pydantic import BaseModel, ConfigDict, Field | ||
|
|
||
| from omnibase_core.enums.replay.enum_override_injection_point import ( | ||
| EnumOverrideInjectionPoint, | ||
| ) | ||
|
|
||
| __all__ = ["ModelConfigOverride"] | ||
|
|
||
|
|
||
| class ModelConfigOverride(BaseModel): | ||
| """ | ||
| A single configuration override specification. | ||
|
|
||
| Attributes: | ||
| path: Dot-separated path to the config field (e.g., "llm.openai.temperature"). | ||
| value: The new value to set at this path. | ||
| injection_point: Where to apply this override (handler_config, environment, context). | ||
|
|
||
| Thread Safety: | ||
| Immutable (frozen=True) after creation - thread-safe for concurrent reads. | ||
|
|
||
| Example: | ||
| >>> override = ModelConfigOverride( | ||
| ... path="llm.temperature", | ||
| ... value=0.7, | ||
| ... injection_point=EnumOverrideInjectionPoint.HANDLER_CONFIG, | ||
| ... ) | ||
| """ | ||
|
|
||
| # from_attributes=True: Enables construction from ORM/dataclass instances | ||
| # and ensures pytest-xdist compatibility across worker processes where | ||
| # class identity may differ due to independent imports. | ||
| # See CLAUDE.md "Pydantic from_attributes=True for Value Objects". | ||
| model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True) | ||
|
|
||
| path: str = Field( | ||
| ..., | ||
| min_length=1, | ||
| description="Dot-separated path to the config field", | ||
| ) | ||
| value: Any = Field( | ||
| ..., | ||
| description="The new value to set at this path", | ||
| ) | ||
| injection_point: EnumOverrideInjectionPoint = Field( | ||
| default=EnumOverrideInjectionPoint.HANDLER_CONFIG, | ||
| description="Where to apply this override", | ||
| ) |
104 changes: 104 additions & 0 deletions
104
src/omnibase_core/models/replay/model_config_override_field_preview.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # SPDX-FileCopyrightText: 2025 OmniNode Team <info@omninode.ai> | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| """ | ||
| Single field preview showing before/after state for one config override. | ||
|
|
||
| .. versionadded:: 0.4.0 | ||
| Added Configuration Override Injection (OMN-1205) | ||
| """ | ||
|
|
||
| from typing import Any | ||
|
|
||
| from pydantic import BaseModel, ConfigDict, Field | ||
|
|
||
| from omnibase_core.enums.replay.enum_override_injection_point import ( | ||
| EnumOverrideInjectionPoint, | ||
| ) | ||
|
|
||
| __all__ = ["ModelConfigOverrideFieldPreview"] | ||
|
|
||
|
|
||
| class ModelConfigOverrideFieldPreview(BaseModel): | ||
| """ | ||
| Single field preview showing before/after for one override. | ||
|
|
||
| Represents the state change for a single configuration field when an | ||
| override is applied. Used for dry-run preview and user confirmation. | ||
|
|
||
| Attributes: | ||
| path: Dot-separated path to the field (e.g., "retry.max_attempts"). | ||
| injection_point: Where this override will be applied in the pipeline. | ||
| old_value: Value before override (or MISSING sentinel for new fields). | ||
| new_value: Value after override. | ||
| value_type: Type of the new value (for display purposes). | ||
| path_exists: Whether the path exists in the original configuration. | ||
|
|
||
| Thread Safety: | ||
| Immutable (frozen=True) after creation - thread-safe for concurrent reads. | ||
|
|
||
| Example: | ||
| >>> preview = ModelConfigOverrideFieldPreview( | ||
| ... path="timeout", | ||
| ... injection_point=EnumOverrideInjectionPoint.HANDLER_CONFIG, | ||
| ... old_value=30, | ||
| ... new_value=60, | ||
| ... value_type="int", | ||
| ... path_exists=True, | ||
| ... ) | ||
| >>> preview.to_markdown_row() | ||
| '| timeout | handler_config | `30` | `60` | exists |' | ||
|
|
||
| .. versionadded:: 0.4.0 | ||
| """ | ||
|
|
||
| # from_attributes=True: Enables construction from ORM/dataclass instances | ||
| # and ensures pytest-xdist compatibility across worker processes where | ||
| # class identity may differ due to independent imports. | ||
| # See CLAUDE.md "Pydantic from_attributes=True for Value Objects". | ||
| model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True) | ||
|
|
||
| path: str = Field(..., description="Dot-separated path to the field") | ||
| injection_point: EnumOverrideInjectionPoint = Field( | ||
| ..., description="Where this override will be applied" | ||
| ) | ||
| old_value: Any = Field( | ||
| ..., description="Value before override (or MISSING sentinel)" | ||
| ) | ||
| new_value: Any = Field(..., description="Value after override") | ||
| value_type: str = Field(default="unknown", description="Type of the new value") | ||
| path_exists: bool = Field( | ||
| default=True, description="Whether the path exists in original" | ||
| ) | ||
|
|
||
| def to_markdown_row(self) -> str: | ||
| """Generate markdown table row for this preview. | ||
|
|
||
| Creates a formatted markdown table row showing the field path, | ||
| injection point, before/after values, and existence status. | ||
|
|
||
| Returns: | ||
| A markdown table row string with pipe delimiters. | ||
| """ | ||
| old_str = self._format_value(self.old_value) | ||
| new_str = self._format_value(self.new_value) | ||
| status = "exists" if self.path_exists else "NEW" | ||
| return f"| {self.path} | {self.injection_point.value} | {old_str} | {new_str} | {status} |" | ||
|
|
||
| def _format_value(self, value: Any) -> str: | ||
| """Format value for markdown display. | ||
|
|
||
| Wraps values in backticks for code formatting. Handles None | ||
| specially as `null` and strings with quotes. | ||
|
|
||
| Args: | ||
| value: The value to format. | ||
|
|
||
| Returns: | ||
| A markdown-formatted string representation of the value. | ||
| """ | ||
| if value is None: | ||
| return "`null`" | ||
| if isinstance(value, str): | ||
| return f'`"{value}"`' | ||
| return f"`{value}`" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.