omnibase_infra 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omnibase_infra/__init__.py +1 -1
- omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
- omnibase_infra/capabilities/__init__.py +15 -0
- omnibase_infra/capabilities/capability_inference_rules.py +211 -0
- omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
- omnibase_infra/capabilities/intent_type_extractor.py +160 -0
- omnibase_infra/cli/commands.py +1 -1
- omnibase_infra/configs/widget_mapping.yaml +176 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +5 -2
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +5 -2
- omnibase_infra/enums/__init__.py +6 -0
- omnibase_infra/enums/enum_handler_error_type.py +10 -0
- omnibase_infra/enums/enum_handler_source_mode.py +72 -0
- omnibase_infra/enums/enum_kafka_acks.py +99 -0
- omnibase_infra/errors/error_compute_registry.py +4 -1
- omnibase_infra/errors/error_event_bus_registry.py +4 -1
- omnibase_infra/errors/error_infra.py +3 -1
- omnibase_infra/errors/error_policy_registry.py +4 -1
- omnibase_infra/event_bus/event_bus_kafka.py +1 -1
- omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +59 -10
- omnibase_infra/handlers/__init__.py +8 -1
- omnibase_infra/handlers/handler_consul.py +7 -1
- omnibase_infra/handlers/handler_db.py +10 -3
- omnibase_infra/handlers/handler_graph.py +10 -5
- omnibase_infra/handlers/handler_http.py +8 -2
- omnibase_infra/handlers/handler_intent.py +387 -0
- omnibase_infra/handlers/handler_mcp.py +745 -63
- omnibase_infra/handlers/handler_vault.py +11 -5
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +4 -3
- omnibase_infra/handlers/mixins/mixin_consul_service.py +2 -1
- omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +7 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +308 -4
- omnibase_infra/handlers/service_discovery/models/model_service_info.py +10 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +3 -2
- omnibase_infra/mixins/mixin_node_introspection.py +42 -7
- omnibase_infra/mixins/mixin_retry_execution.py +1 -1
- omnibase_infra/models/discovery/model_introspection_config.py +11 -0
- omnibase_infra/models/handlers/__init__.py +48 -5
- omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +6 -4
- omnibase_infra/models/handlers/model_handler_descriptor.py +15 -0
- omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
- omnibase_infra/models/mcp/__init__.py +15 -0
- omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
- omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
- omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
- omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
- omnibase_infra/models/registration/model_node_capabilities.py +11 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +9 -0
- omnibase_infra/models/runtime/model_handler_contract.py +25 -9
- omnibase_infra/models/runtime/model_loaded_handler.py +9 -0
- omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +0 -5
- omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +17 -10
- omnibase_infra/nodes/effects/contract.yaml +0 -5
- omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +7 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +86 -1
- omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +3 -3
- omnibase_infra/nodes/node_registration_orchestrator/plugin.py +1 -1
- omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +9 -8
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +4 -3
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +14 -13
- omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +0 -5
- omnibase_infra/nodes/node_registration_storage_effect/node.py +4 -1
- omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +47 -26
- omnibase_infra/nodes/node_registry_effect/contract.yaml +0 -5
- omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +2 -1
- omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +28 -20
- omnibase_infra/plugins/examples/plugin_json_normalizer.py +2 -2
- omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +2 -2
- omnibase_infra/plugins/plugin_compute_base.py +16 -2
- omnibase_infra/protocols/__init__.py +2 -0
- omnibase_infra/protocols/protocol_container_aware.py +200 -0
- omnibase_infra/protocols/protocol_event_projector.py +1 -1
- omnibase_infra/runtime/__init__.py +90 -1
- omnibase_infra/runtime/binding_config_resolver.py +102 -37
- omnibase_infra/runtime/constants_notification.py +75 -0
- omnibase_infra/runtime/contract_handler_discovery.py +6 -1
- omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
- omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
- omnibase_infra/runtime/handler_contract_source.py +267 -186
- omnibase_infra/runtime/handler_identity.py +81 -0
- omnibase_infra/runtime/handler_plugin_loader.py +19 -2
- omnibase_infra/runtime/handler_registry.py +11 -3
- omnibase_infra/runtime/handler_source_resolver.py +326 -0
- omnibase_infra/runtime/mixin_semver_cache.py +25 -1
- omnibase_infra/runtime/mixins/__init__.py +7 -0
- omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +31 -10
- omnibase_infra/runtime/models/__init__.py +24 -0
- omnibase_infra/runtime/models/model_health_check_result.py +2 -1
- omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
- omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
- omnibase_infra/runtime/projector_plugin_loader.py +1 -1
- omnibase_infra/runtime/projector_shell.py +229 -1
- omnibase_infra/runtime/protocol_lifecycle_executor.py +6 -6
- omnibase_infra/runtime/protocols/__init__.py +10 -0
- omnibase_infra/runtime/registry/registry_protocol_binding.py +16 -15
- omnibase_infra/runtime/registry_contract_source.py +693 -0
- omnibase_infra/runtime/registry_policy.py +9 -326
- omnibase_infra/runtime/secret_resolver.py +4 -2
- omnibase_infra/runtime/service_kernel.py +11 -3
- omnibase_infra/runtime/service_message_dispatch_engine.py +4 -2
- omnibase_infra/runtime/service_runtime_host_process.py +589 -106
- omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
- omnibase_infra/runtime/transition_notification_publisher.py +764 -0
- omnibase_infra/runtime/util_container_wiring.py +6 -5
- omnibase_infra/runtime/util_wiring.py +17 -4
- omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
- omnibase_infra/services/__init__.py +21 -0
- omnibase_infra/services/corpus_capture.py +7 -1
- omnibase_infra/services/mcp/__init__.py +31 -0
- omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
- omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
- omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
- omnibase_infra/services/mcp/service_mcp_tool_sync.py +547 -0
- omnibase_infra/services/registry_api/__init__.py +40 -0
- omnibase_infra/services/registry_api/main.py +261 -0
- omnibase_infra/services/registry_api/models/__init__.py +66 -0
- omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
- omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
- omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
- omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
- omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
- omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
- omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
- omnibase_infra/services/registry_api/models/model_warning.py +49 -0
- omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
- omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
- omnibase_infra/services/registry_api/routes.py +371 -0
- omnibase_infra/services/registry_api/service.py +837 -0
- omnibase_infra/services/service_capability_query.py +4 -4
- omnibase_infra/services/service_health.py +3 -2
- omnibase_infra/services/service_timeout_emitter.py +20 -3
- omnibase_infra/services/service_timeout_scanner.py +7 -3
- omnibase_infra/services/session/__init__.py +56 -0
- omnibase_infra/services/session/config_consumer.py +120 -0
- omnibase_infra/services/session/config_store.py +139 -0
- omnibase_infra/services/session/consumer.py +1007 -0
- omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
- omnibase_infra/services/session/store.py +997 -0
- omnibase_infra/utils/__init__.py +19 -0
- omnibase_infra/utils/util_atomic_file.py +261 -0
- omnibase_infra/utils/util_db_transaction.py +239 -0
- omnibase_infra/utils/util_dsn_validation.py +1 -1
- omnibase_infra/utils/util_retry_optimistic.py +281 -0
- omnibase_infra/validation/__init__.py +3 -19
- omnibase_infra/validation/contracts/security.validation.yaml +114 -0
- omnibase_infra/validation/infra_validators.py +35 -24
- omnibase_infra/validation/validation_exemptions.yaml +140 -9
- omnibase_infra/validation/validator_chain_propagation.py +2 -2
- omnibase_infra/validation/validator_runtime_shape.py +1 -1
- omnibase_infra/validation/validator_security.py +473 -370
- {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/METADATA +3 -3
- {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/RECORD +161 -98
- {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/WHEEL +0 -0
- {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/entry_points.txt +0 -0
- {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -90,13 +90,22 @@ from omnibase_infra.runtime.service_kernel import load_runtime_config
|
|
|
90
90
|
from omnibase_infra.runtime.service_kernel import main as kernel_main
|
|
91
91
|
from omnibase_infra.runtime.service_message_dispatch_engine import MessageDispatchEngine
|
|
92
92
|
from omnibase_infra.runtime.models import (
|
|
93
|
+
ModelProjectorNotificationConfig,
|
|
93
94
|
ModelRuntimeSchedulerConfig,
|
|
94
95
|
ModelRuntimeSchedulerMetrics,
|
|
95
96
|
ModelRuntimeTick,
|
|
97
|
+
ModelStateTransitionNotification,
|
|
98
|
+
ModelTransitionNotificationPublisherMetrics,
|
|
96
99
|
)
|
|
97
100
|
from omnibase_infra.runtime.registry_policy import RegistryPolicy
|
|
98
101
|
from omnibase_infra.runtime.protocol_policy import ProtocolPolicy
|
|
99
|
-
from omnibase_infra.runtime.protocols import
|
|
102
|
+
from omnibase_infra.runtime.protocols import (
|
|
103
|
+
ProtocolRuntimeScheduler,
|
|
104
|
+
ProtocolTransitionNotificationPublisher,
|
|
105
|
+
)
|
|
106
|
+
from omnibase_infra.runtime.mixins import (
|
|
107
|
+
ProtocolProjectorNotificationContext,
|
|
108
|
+
)
|
|
100
109
|
from omnibase_infra.runtime.registry import (
|
|
101
110
|
MessageTypeRegistryError,
|
|
102
111
|
ModelDomainConstraint,
|
|
@@ -145,6 +154,28 @@ from omnibase_infra.runtime.handler_plugin_loader import (
|
|
|
145
154
|
MAX_CONTRACT_SIZE,
|
|
146
155
|
)
|
|
147
156
|
|
|
157
|
+
# Handler bootstrap source (OMN-1087)
|
|
158
|
+
from omnibase_infra.runtime.handler_bootstrap_source import (
|
|
159
|
+
HandlerBootstrapSource,
|
|
160
|
+
SOURCE_TYPE_BOOTSTRAP,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Handler identity helper (OMN-1095)
|
|
164
|
+
from omnibase_infra.runtime.handler_identity import (
|
|
165
|
+
HANDLER_IDENTITY_PREFIX,
|
|
166
|
+
handler_identity,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Handler source resolver (OMN-1095)
|
|
170
|
+
from omnibase_infra.runtime.handler_source_resolver import HandlerSourceResolver
|
|
171
|
+
|
|
172
|
+
# Handler contract config loader
|
|
173
|
+
from omnibase_infra.runtime.handler_contract_config_loader import (
|
|
174
|
+
MAX_CONTRACT_SIZE_BYTES,
|
|
175
|
+
extract_handler_config,
|
|
176
|
+
load_handler_contract_config,
|
|
177
|
+
)
|
|
178
|
+
|
|
148
179
|
# Binding config resolver (OMN-765)
|
|
149
180
|
from omnibase_infra.runtime.binding_config_resolver import BindingConfigResolver
|
|
150
181
|
from omnibase_infra.runtime.protocol_handler_plugin_loader import (
|
|
@@ -181,6 +212,29 @@ from omnibase_infra.runtime.security_metadata_validator import (
|
|
|
181
212
|
validate_handler_security,
|
|
182
213
|
)
|
|
183
214
|
|
|
215
|
+
# Transition notification publisher and outbox (OMN-1139)
|
|
216
|
+
from omnibase_infra.runtime.constants_notification import FROM_STATE_INITIAL
|
|
217
|
+
from omnibase_infra.runtime.transition_notification_publisher import (
|
|
218
|
+
TransitionNotificationPublisher,
|
|
219
|
+
)
|
|
220
|
+
from omnibase_infra.runtime.transition_notification_outbox import (
|
|
221
|
+
TransitionNotificationOutbox,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Registry contract source (OMN-1100)
|
|
225
|
+
from omnibase_infra.runtime.registry_contract_source import (
|
|
226
|
+
DEFAULT_CONSUL_HOST,
|
|
227
|
+
DEFAULT_CONSUL_PORT,
|
|
228
|
+
DEFAULT_CONTRACT_PREFIX,
|
|
229
|
+
RegistryContractSource,
|
|
230
|
+
adelete_contract_from_consul,
|
|
231
|
+
alist_contracts_in_consul,
|
|
232
|
+
astore_contract_in_consul,
|
|
233
|
+
delete_contract_from_consul,
|
|
234
|
+
list_contracts_in_consul,
|
|
235
|
+
store_contract_in_consul,
|
|
236
|
+
)
|
|
237
|
+
|
|
184
238
|
# Chain-aware dispatch (OMN-951) - must be imported LAST to avoid circular import
|
|
185
239
|
from omnibase_infra.runtime.chain_aware_dispatch import (
|
|
186
240
|
ChainAwareDispatcher,
|
|
@@ -214,9 +268,12 @@ __all__: list[str] = [
|
|
|
214
268
|
"MessageTypeRegistryError",
|
|
215
269
|
"ModelDomainConstraint",
|
|
216
270
|
"ModelMessageTypeEntry",
|
|
271
|
+
"ModelProjectorNotificationConfig",
|
|
217
272
|
"ModelRuntimeSchedulerConfig",
|
|
218
273
|
"ModelRuntimeSchedulerMetrics",
|
|
219
274
|
"ModelRuntimeTick",
|
|
275
|
+
"ModelStateTransitionNotification",
|
|
276
|
+
"ModelTransitionNotificationPublisherMetrics",
|
|
220
277
|
"ProtocolMessageDispatcher",
|
|
221
278
|
"ProtocolMessageTypeRegistry",
|
|
222
279
|
# Registry classes
|
|
@@ -230,8 +287,14 @@ __all__: list[str] = [
|
|
|
230
287
|
"RegistryDispatcher",
|
|
231
288
|
# Runtime scheduler (OMN-953)
|
|
232
289
|
"ProtocolRuntimeScheduler",
|
|
290
|
+
# Transition notification (OMN-1139)
|
|
291
|
+
"ProtocolTransitionNotificationPublisher",
|
|
292
|
+
# Projector notification context protocol (OMN-1139)
|
|
293
|
+
"ProtocolProjectorNotificationContext",
|
|
233
294
|
# Error class
|
|
234
295
|
"RegistryError",
|
|
296
|
+
# Notification constants (OMN-1139)
|
|
297
|
+
"FROM_STATE_INITIAL",
|
|
235
298
|
# Runtime host
|
|
236
299
|
"RuntimeHostProcess",
|
|
237
300
|
"RuntimeScheduler",
|
|
@@ -277,6 +340,18 @@ __all__: list[str] = [
|
|
|
277
340
|
"HandlerPluginLoader",
|
|
278
341
|
"MAX_CONTRACT_SIZE",
|
|
279
342
|
"ProtocolHandlerPluginLoader",
|
|
343
|
+
# Handler bootstrap source (OMN-1087)
|
|
344
|
+
"HandlerBootstrapSource",
|
|
345
|
+
"SOURCE_TYPE_BOOTSTRAP",
|
|
346
|
+
# Handler identity helper (OMN-1095)
|
|
347
|
+
"HANDLER_IDENTITY_PREFIX",
|
|
348
|
+
"handler_identity",
|
|
349
|
+
# Handler source resolver (OMN-1095)
|
|
350
|
+
"HandlerSourceResolver",
|
|
351
|
+
# Handler contract config loader
|
|
352
|
+
"MAX_CONTRACT_SIZE_BYTES",
|
|
353
|
+
"extract_handler_config",
|
|
354
|
+
"load_handler_contract_config",
|
|
280
355
|
# Binding config resolver (OMN-765)
|
|
281
356
|
"BindingConfigResolver",
|
|
282
357
|
# Handler discovery protocol and implementation (OMN-1133)
|
|
@@ -293,4 +368,18 @@ __all__: list[str] = [
|
|
|
293
368
|
# Security metadata validator (OMN-1137)
|
|
294
369
|
"SecurityMetadataValidator",
|
|
295
370
|
"validate_handler_security",
|
|
371
|
+
# Transition notification publisher and outbox (OMN-1139)
|
|
372
|
+
"TransitionNotificationOutbox",
|
|
373
|
+
"TransitionNotificationPublisher",
|
|
374
|
+
# Registry contract source (OMN-1100)
|
|
375
|
+
"DEFAULT_CONSUL_HOST",
|
|
376
|
+
"DEFAULT_CONSUL_PORT",
|
|
377
|
+
"DEFAULT_CONTRACT_PREFIX",
|
|
378
|
+
"RegistryContractSource",
|
|
379
|
+
"adelete_contract_from_consul",
|
|
380
|
+
"alist_contracts_in_consul",
|
|
381
|
+
"astore_contract_in_consul",
|
|
382
|
+
"delete_contract_from_consul",
|
|
383
|
+
"list_contracts_in_consul",
|
|
384
|
+
"store_contract_in_consul",
|
|
296
385
|
]
|
|
@@ -56,10 +56,12 @@ Example:
|
|
|
56
56
|
# Bootstrap container and register config
|
|
57
57
|
container = ModelONEXContainer()
|
|
58
58
|
config = ModelBindingConfigResolverConfig(env_prefix="HANDLER")
|
|
59
|
+
from omnibase_core.enums import EnumInjectionScope
|
|
60
|
+
|
|
59
61
|
await container.service_registry.register_instance(
|
|
60
62
|
interface=ModelBindingConfigResolverConfig,
|
|
61
63
|
instance=config,
|
|
62
|
-
scope=
|
|
64
|
+
scope=EnumInjectionScope.GLOBAL,
|
|
63
65
|
)
|
|
64
66
|
|
|
65
67
|
# Create resolver with container injection
|
|
@@ -235,14 +237,15 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
235
237
|
|
|
236
238
|
Example:
|
|
237
239
|
>>> # Container setup (async context required)
|
|
240
|
+
>>> from omnibase_core.enums import EnumInjectionScope
|
|
238
241
|
>>> container = ModelONEXContainer()
|
|
239
242
|
>>> config = ModelBindingConfigResolverConfig(env_prefix="HANDLER")
|
|
240
243
|
>>> await container.service_registry.register_instance(
|
|
241
244
|
... interface=ModelBindingConfigResolverConfig,
|
|
242
245
|
... instance=config,
|
|
243
|
-
... scope=
|
|
246
|
+
... scope=EnumInjectionScope.GLOBAL,
|
|
244
247
|
... )
|
|
245
|
-
>>> resolver = BindingConfigResolver(container)
|
|
248
|
+
>>> resolver = await BindingConfigResolver.create(container)
|
|
246
249
|
>>> binding = resolver.resolve(
|
|
247
250
|
... handler_type="db",
|
|
248
251
|
... inline_config={"pool_size": 10}
|
|
@@ -252,6 +255,9 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
252
255
|
def __init__(
|
|
253
256
|
self,
|
|
254
257
|
container: ModelONEXContainer,
|
|
258
|
+
*,
|
|
259
|
+
_config: ModelBindingConfigResolverConfig | None = None,
|
|
260
|
+
_secret_resolver: SecretResolver | None = None,
|
|
255
261
|
) -> None:
|
|
256
262
|
"""Initialize BindingConfigResolver with container-based dependency injection.
|
|
257
263
|
|
|
@@ -259,52 +265,37 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
259
265
|
Config is resolved from container's service registry, and SecretResolver
|
|
260
266
|
is resolved as an optional dependency.
|
|
261
267
|
|
|
268
|
+
Note:
|
|
269
|
+
Prefer using the async factory method ``create()`` for initialization,
|
|
270
|
+
which properly resolves dependencies from the container's service registry.
|
|
271
|
+
Direct ``__init__`` usage requires pre-resolved config and secret_resolver.
|
|
272
|
+
|
|
262
273
|
Args:
|
|
263
274
|
container: ONEX container for dependency resolution.
|
|
275
|
+
_config: Pre-resolved config (used by create() factory). If None, raises error.
|
|
276
|
+
_secret_resolver: Pre-resolved secret resolver (optional, used by create() factory).
|
|
264
277
|
|
|
265
278
|
Raises:
|
|
266
|
-
ProtocolConfigurationError: If
|
|
267
|
-
in the container's service registry.
|
|
279
|
+
ProtocolConfigurationError: If _config is not provided (use create() instead).
|
|
268
280
|
"""
|
|
269
281
|
self._container = container
|
|
270
282
|
|
|
271
|
-
#
|
|
272
|
-
|
|
273
|
-
self._config: ModelBindingConfigResolverConfig = (
|
|
274
|
-
container.service_registry.resolve_service(
|
|
275
|
-
ModelBindingConfigResolverConfig
|
|
276
|
-
)
|
|
277
|
-
)
|
|
278
|
-
except (LookupError, KeyError, TypeError, AttributeError) as e:
|
|
279
|
-
# LookupError/KeyError: service not registered
|
|
280
|
-
# TypeError: invalid interface specification
|
|
281
|
-
# AttributeError: container/registry missing expected methods
|
|
283
|
+
# Validate that config was provided (either via create() or directly)
|
|
284
|
+
if _config is None:
|
|
282
285
|
context = ModelInfraErrorContext.with_correlation(
|
|
283
286
|
transport_type=EnumInfraTransportType.RUNTIME,
|
|
284
287
|
operation="init",
|
|
285
288
|
target_name="binding_config_resolver",
|
|
286
289
|
)
|
|
287
290
|
raise ProtocolConfigurationError(
|
|
288
|
-
"
|
|
289
|
-
"
|
|
291
|
+
"BindingConfigResolver requires config to be provided. "
|
|
292
|
+
"Use the async factory method BindingConfigResolver.create(container) "
|
|
293
|
+
"for proper initialization with dependency resolution.",
|
|
290
294
|
context=context,
|
|
291
|
-
) from e
|
|
292
|
-
|
|
293
|
-
# Resolve SecretResolver from container (optional dependency)
|
|
294
|
-
# This replaces the config.secret_resolver pattern
|
|
295
|
-
self._secret_resolver: SecretResolver | None = None
|
|
296
|
-
try:
|
|
297
|
-
from omnibase_infra.runtime.secret_resolver import SecretResolver
|
|
298
|
-
|
|
299
|
-
self._secret_resolver = container.service_registry.resolve_service(
|
|
300
|
-
SecretResolver
|
|
301
295
|
)
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
# KeyError: SecretResolver not registered in service registry
|
|
306
|
-
# AttributeError: service_registry missing resolve_service method (test mocks)
|
|
307
|
-
pass
|
|
296
|
+
|
|
297
|
+
self._config: ModelBindingConfigResolverConfig = _config
|
|
298
|
+
self._secret_resolver: SecretResolver | None = _secret_resolver
|
|
308
299
|
|
|
309
300
|
# Use OrderedDict for LRU eviction support - entries are moved to end on access
|
|
310
301
|
self._cache: OrderedDict[str, ModelConfigCacheEntry] = OrderedDict()
|
|
@@ -357,6 +348,80 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
357
348
|
self._async_key_locks: dict[str, asyncio.Lock] = {}
|
|
358
349
|
self._async_key_lock_timestamps: dict[str, float] = {}
|
|
359
350
|
|
|
351
|
+
@classmethod
|
|
352
|
+
async def create(
|
|
353
|
+
cls,
|
|
354
|
+
container: ModelONEXContainer,
|
|
355
|
+
) -> BindingConfigResolver:
|
|
356
|
+
"""Async factory method for creating BindingConfigResolver with proper DI.
|
|
357
|
+
|
|
358
|
+
This is the preferred method for creating BindingConfigResolver instances.
|
|
359
|
+
It properly resolves dependencies from the container's async service registry.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
container: ONEX container for dependency resolution.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Fully initialized BindingConfigResolver instance.
|
|
366
|
+
|
|
367
|
+
Raises:
|
|
368
|
+
ProtocolConfigurationError: If ModelBindingConfigResolverConfig is not registered
|
|
369
|
+
in the container's service registry.
|
|
370
|
+
|
|
371
|
+
Example:
|
|
372
|
+
>>> from omnibase_core.enums import EnumInjectionScope
|
|
373
|
+
>>> container = ModelONEXContainer()
|
|
374
|
+
>>> config = ModelBindingConfigResolverConfig(env_prefix="HANDLER")
|
|
375
|
+
>>> await container.service_registry.register_instance(
|
|
376
|
+
... interface=ModelBindingConfigResolverConfig,
|
|
377
|
+
... instance=config,
|
|
378
|
+
... scope=EnumInjectionScope.GLOBAL,
|
|
379
|
+
... )
|
|
380
|
+
>>> resolver = await BindingConfigResolver.create(container)
|
|
381
|
+
"""
|
|
382
|
+
# Resolve config from container's service registry
|
|
383
|
+
try:
|
|
384
|
+
config: ModelBindingConfigResolverConfig = (
|
|
385
|
+
await container.service_registry.resolve_service(
|
|
386
|
+
ModelBindingConfigResolverConfig
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
except (LookupError, KeyError, TypeError, AttributeError) as e:
|
|
390
|
+
# LookupError/KeyError: service not registered
|
|
391
|
+
# TypeError: invalid interface specification
|
|
392
|
+
# AttributeError: container/registry missing expected methods
|
|
393
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
394
|
+
transport_type=EnumInfraTransportType.RUNTIME,
|
|
395
|
+
operation="create",
|
|
396
|
+
target_name="binding_config_resolver",
|
|
397
|
+
)
|
|
398
|
+
raise ProtocolConfigurationError(
|
|
399
|
+
"Failed to resolve ModelBindingConfigResolverConfig from container. "
|
|
400
|
+
"Ensure config is registered via container.service_registry.register_instance().",
|
|
401
|
+
context=context,
|
|
402
|
+
) from e
|
|
403
|
+
|
|
404
|
+
# Resolve SecretResolver from container (optional dependency)
|
|
405
|
+
secret_resolver: SecretResolver | None = None
|
|
406
|
+
try:
|
|
407
|
+
from omnibase_infra.runtime.secret_resolver import SecretResolver
|
|
408
|
+
|
|
409
|
+
secret_resolver = await container.service_registry.resolve_service(
|
|
410
|
+
SecretResolver
|
|
411
|
+
)
|
|
412
|
+
except (ImportError, KeyError, AttributeError):
|
|
413
|
+
# SecretResolver is optional - if not registered, vault: schemes won't work
|
|
414
|
+
# ImportError: SecretResolver module not available
|
|
415
|
+
# KeyError: SecretResolver not registered in service registry
|
|
416
|
+
# AttributeError: service_registry missing resolve_service method (test mocks)
|
|
417
|
+
pass
|
|
418
|
+
|
|
419
|
+
return cls(
|
|
420
|
+
container,
|
|
421
|
+
_config=config,
|
|
422
|
+
_secret_resolver=secret_resolver,
|
|
423
|
+
)
|
|
424
|
+
|
|
360
425
|
# === Primary API (Sync) ===
|
|
361
426
|
|
|
362
427
|
def resolve(
|
|
@@ -533,7 +598,7 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
533
598
|
result = await self._resolve_config_async(
|
|
534
599
|
handler_type=handler_type,
|
|
535
600
|
config_ref=config_ref,
|
|
536
|
-
inline_config=inline_config,
|
|
601
|
+
inline_config=inline_config, # type: ignore[arg-type]
|
|
537
602
|
correlation_id=correlation_id,
|
|
538
603
|
)
|
|
539
604
|
|
|
@@ -917,7 +982,7 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
917
982
|
def _describe_source(
|
|
918
983
|
self,
|
|
919
984
|
config_ref: str | None,
|
|
920
|
-
inline_config: dict[str,
|
|
985
|
+
inline_config: dict[str, JsonType] | None,
|
|
921
986
|
) -> str:
|
|
922
987
|
"""Create a description of the configuration source for debugging.
|
|
923
988
|
|
|
@@ -945,7 +1010,7 @@ class BindingConfigResolver: # ONEX_EXCLUDE: method_count - follows SecretResol
|
|
|
945
1010
|
self,
|
|
946
1011
|
handler_type: str,
|
|
947
1012
|
config_ref: str | None,
|
|
948
|
-
inline_config: dict[str,
|
|
1013
|
+
inline_config: dict[str, JsonType] | None,
|
|
949
1014
|
correlation_id: UUID,
|
|
950
1015
|
) -> ModelBindingConfig:
|
|
951
1016
|
"""Resolve configuration from sources synchronously.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Notification Constants Module.
|
|
4
|
+
|
|
5
|
+
Provides constants for notification publishing, particularly for state
|
|
6
|
+
transition notifications used by projectors and orchestrators.
|
|
7
|
+
|
|
8
|
+
Sentinel Values
|
|
9
|
+
---------------
|
|
10
|
+
- **FROM_STATE_INITIAL**: Sentinel value used when publishing a state transition
|
|
11
|
+
notification for a NEW entity (one that didn't exist before the projection).
|
|
12
|
+
This is used instead of an empty string to provide clear semantic meaning.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
>>> from omnibase_infra.runtime.constants_notification import FROM_STATE_INITIAL
|
|
16
|
+
>>>
|
|
17
|
+
>>> # In notification publishing code:
|
|
18
|
+
>>> effective_from_state = from_state if from_state is not None else FROM_STATE_INITIAL
|
|
19
|
+
>>>
|
|
20
|
+
>>> # In notification consumers:
|
|
21
|
+
>>> if notification.from_state == FROM_STATE_INITIAL:
|
|
22
|
+
... # This is a new entity, not a state transition from existing state
|
|
23
|
+
... handle_new_entity(notification)
|
|
24
|
+
|
|
25
|
+
Why Not Empty String?
|
|
26
|
+
Using an empty string ("") for new entities is semantically ambiguous:
|
|
27
|
+
- An empty string could be confused with an actual empty state value
|
|
28
|
+
- It doesn't clearly communicate "this entity was just created"
|
|
29
|
+
- Consumers cannot distinguish between "no previous state" and "empty state"
|
|
30
|
+
|
|
31
|
+
The "__INITIAL__" sentinel provides:
|
|
32
|
+
- Clear semantic meaning (obviously not a real FSM state name)
|
|
33
|
+
- Easy detection in consumer code
|
|
34
|
+
- Explicit intent communication
|
|
35
|
+
|
|
36
|
+
Related:
|
|
37
|
+
- ModelStateTransitionNotification: The notification model that uses this value
|
|
38
|
+
- MixinProjectorNotificationPublishing: The mixin that sets this value
|
|
39
|
+
- TransitionNotificationPublisher: The publisher that emits these notifications
|
|
40
|
+
|
|
41
|
+
Related Tickets:
|
|
42
|
+
- OMN-1139: Integrate TransitionNotificationPublisher with ProjectorShell
|
|
43
|
+
|
|
44
|
+
.. versionadded:: 0.8.0
|
|
45
|
+
Created as part of OMN-1139 notification integration.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
from typing import Final
|
|
49
|
+
|
|
50
|
+
# Sentinel value for from_state when publishing notifications for NEW entities.
|
|
51
|
+
# This indicates the entity was just created and has no previous state.
|
|
52
|
+
# Consumers can check: if notification.from_state == FROM_STATE_INITIAL
|
|
53
|
+
FROM_STATE_INITIAL: Final[str] = "__INITIAL__"
|
|
54
|
+
"""Sentinel value indicating a new entity with no previous state.
|
|
55
|
+
|
|
56
|
+
This value is used as the ``from_state`` field in ModelStateTransitionNotification
|
|
57
|
+
when publishing a notification for a newly created entity. It replaces the
|
|
58
|
+
semantically ambiguous empty string ("") with a clear, distinguishable marker.
|
|
59
|
+
|
|
60
|
+
Example:
|
|
61
|
+
>>> notification = ModelStateTransitionNotification(
|
|
62
|
+
... aggregate_type="registration",
|
|
63
|
+
... aggregate_id=uuid4(),
|
|
64
|
+
... from_state=FROM_STATE_INITIAL, # New entity
|
|
65
|
+
... to_state="pending",
|
|
66
|
+
... # ... other fields
|
|
67
|
+
... )
|
|
68
|
+
|
|
69
|
+
Note:
|
|
70
|
+
The double underscore prefix/suffix convention (``__INITIAL__``) follows
|
|
71
|
+
Python's pattern for special/dunder values, making it obviously not a
|
|
72
|
+
real FSM state name that would be used in domain logic.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
__all__: list[str] = ["FROM_STATE_INITIAL"]
|
|
@@ -437,7 +437,12 @@ class ContractHandlerDiscovery:
|
|
|
437
437
|
if hasattr(e, "model") and hasattr(e.model, "context"):
|
|
438
438
|
context_dict = e.model.context
|
|
439
439
|
if isinstance(context_dict, dict):
|
|
440
|
-
|
|
440
|
+
loader_error = context_dict.get("loader_error")
|
|
441
|
+
error_code = (
|
|
442
|
+
str(loader_error)
|
|
443
|
+
if loader_error is not None
|
|
444
|
+
else error_code
|
|
445
|
+
)
|
|
441
446
|
|
|
442
447
|
errors.append(
|
|
443
448
|
ModelDiscoveryError(
|