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.
Files changed (161) hide show
  1. omnibase_infra/__init__.py +1 -1
  2. omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
  3. omnibase_infra/capabilities/__init__.py +15 -0
  4. omnibase_infra/capabilities/capability_inference_rules.py +211 -0
  5. omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
  6. omnibase_infra/capabilities/intent_type_extractor.py +160 -0
  7. omnibase_infra/cli/commands.py +1 -1
  8. omnibase_infra/configs/widget_mapping.yaml +176 -0
  9. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +5 -2
  10. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +5 -2
  11. omnibase_infra/enums/__init__.py +6 -0
  12. omnibase_infra/enums/enum_handler_error_type.py +10 -0
  13. omnibase_infra/enums/enum_handler_source_mode.py +72 -0
  14. omnibase_infra/enums/enum_kafka_acks.py +99 -0
  15. omnibase_infra/errors/error_compute_registry.py +4 -1
  16. omnibase_infra/errors/error_event_bus_registry.py +4 -1
  17. omnibase_infra/errors/error_infra.py +3 -1
  18. omnibase_infra/errors/error_policy_registry.py +4 -1
  19. omnibase_infra/event_bus/event_bus_kafka.py +1 -1
  20. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +59 -10
  21. omnibase_infra/handlers/__init__.py +8 -1
  22. omnibase_infra/handlers/handler_consul.py +7 -1
  23. omnibase_infra/handlers/handler_db.py +10 -3
  24. omnibase_infra/handlers/handler_graph.py +10 -5
  25. omnibase_infra/handlers/handler_http.py +8 -2
  26. omnibase_infra/handlers/handler_intent.py +387 -0
  27. omnibase_infra/handlers/handler_mcp.py +745 -63
  28. omnibase_infra/handlers/handler_vault.py +11 -5
  29. omnibase_infra/handlers/mixins/mixin_consul_kv.py +4 -3
  30. omnibase_infra/handlers/mixins/mixin_consul_service.py +2 -1
  31. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +7 -0
  32. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +308 -4
  33. omnibase_infra/handlers/service_discovery/models/model_service_info.py +10 -0
  34. omnibase_infra/mixins/mixin_async_circuit_breaker.py +3 -2
  35. omnibase_infra/mixins/mixin_node_introspection.py +42 -7
  36. omnibase_infra/mixins/mixin_retry_execution.py +1 -1
  37. omnibase_infra/models/discovery/model_introspection_config.py +11 -0
  38. omnibase_infra/models/handlers/__init__.py +48 -5
  39. omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
  40. omnibase_infra/models/handlers/model_contract_discovery_result.py +6 -4
  41. omnibase_infra/models/handlers/model_handler_descriptor.py +15 -0
  42. omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
  43. omnibase_infra/models/mcp/__init__.py +15 -0
  44. omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
  45. omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
  46. omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
  47. omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
  48. omnibase_infra/models/registration/model_node_capabilities.py +11 -0
  49. omnibase_infra/models/registration/model_node_introspection_event.py +9 -0
  50. omnibase_infra/models/runtime/model_handler_contract.py +25 -9
  51. omnibase_infra/models/runtime/model_loaded_handler.py +9 -0
  52. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +0 -5
  53. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +17 -10
  54. omnibase_infra/nodes/effects/contract.yaml +0 -5
  55. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +7 -0
  56. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +86 -1
  57. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +3 -3
  58. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +1 -1
  59. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +9 -8
  60. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +4 -3
  61. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +14 -13
  62. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +0 -5
  63. omnibase_infra/nodes/node_registration_storage_effect/node.py +4 -1
  64. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +47 -26
  65. omnibase_infra/nodes/node_registry_effect/contract.yaml +0 -5
  66. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +2 -1
  67. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +28 -20
  68. omnibase_infra/plugins/examples/plugin_json_normalizer.py +2 -2
  69. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +2 -2
  70. omnibase_infra/plugins/plugin_compute_base.py +16 -2
  71. omnibase_infra/protocols/__init__.py +2 -0
  72. omnibase_infra/protocols/protocol_container_aware.py +200 -0
  73. omnibase_infra/protocols/protocol_event_projector.py +1 -1
  74. omnibase_infra/runtime/__init__.py +90 -1
  75. omnibase_infra/runtime/binding_config_resolver.py +102 -37
  76. omnibase_infra/runtime/constants_notification.py +75 -0
  77. omnibase_infra/runtime/contract_handler_discovery.py +6 -1
  78. omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
  79. omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
  80. omnibase_infra/runtime/handler_contract_source.py +267 -186
  81. omnibase_infra/runtime/handler_identity.py +81 -0
  82. omnibase_infra/runtime/handler_plugin_loader.py +19 -2
  83. omnibase_infra/runtime/handler_registry.py +11 -3
  84. omnibase_infra/runtime/handler_source_resolver.py +326 -0
  85. omnibase_infra/runtime/mixin_semver_cache.py +25 -1
  86. omnibase_infra/runtime/mixins/__init__.py +7 -0
  87. omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
  88. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +31 -10
  89. omnibase_infra/runtime/models/__init__.py +24 -0
  90. omnibase_infra/runtime/models/model_health_check_result.py +2 -1
  91. omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
  92. omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
  93. omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
  94. omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
  95. omnibase_infra/runtime/projector_plugin_loader.py +1 -1
  96. omnibase_infra/runtime/projector_shell.py +229 -1
  97. omnibase_infra/runtime/protocol_lifecycle_executor.py +6 -6
  98. omnibase_infra/runtime/protocols/__init__.py +10 -0
  99. omnibase_infra/runtime/registry/registry_protocol_binding.py +16 -15
  100. omnibase_infra/runtime/registry_contract_source.py +693 -0
  101. omnibase_infra/runtime/registry_policy.py +9 -326
  102. omnibase_infra/runtime/secret_resolver.py +4 -2
  103. omnibase_infra/runtime/service_kernel.py +11 -3
  104. omnibase_infra/runtime/service_message_dispatch_engine.py +4 -2
  105. omnibase_infra/runtime/service_runtime_host_process.py +589 -106
  106. omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
  107. omnibase_infra/runtime/transition_notification_publisher.py +764 -0
  108. omnibase_infra/runtime/util_container_wiring.py +6 -5
  109. omnibase_infra/runtime/util_wiring.py +17 -4
  110. omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
  111. omnibase_infra/services/__init__.py +21 -0
  112. omnibase_infra/services/corpus_capture.py +7 -1
  113. omnibase_infra/services/mcp/__init__.py +31 -0
  114. omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
  115. omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
  116. omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
  117. omnibase_infra/services/mcp/service_mcp_tool_sync.py +547 -0
  118. omnibase_infra/services/registry_api/__init__.py +40 -0
  119. omnibase_infra/services/registry_api/main.py +261 -0
  120. omnibase_infra/services/registry_api/models/__init__.py +66 -0
  121. omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
  122. omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
  123. omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
  124. omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
  125. omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
  126. omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
  127. omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
  128. omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
  129. omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
  130. omnibase_infra/services/registry_api/models/model_warning.py +49 -0
  131. omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
  132. omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
  133. omnibase_infra/services/registry_api/routes.py +371 -0
  134. omnibase_infra/services/registry_api/service.py +837 -0
  135. omnibase_infra/services/service_capability_query.py +4 -4
  136. omnibase_infra/services/service_health.py +3 -2
  137. omnibase_infra/services/service_timeout_emitter.py +20 -3
  138. omnibase_infra/services/service_timeout_scanner.py +7 -3
  139. omnibase_infra/services/session/__init__.py +56 -0
  140. omnibase_infra/services/session/config_consumer.py +120 -0
  141. omnibase_infra/services/session/config_store.py +139 -0
  142. omnibase_infra/services/session/consumer.py +1007 -0
  143. omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
  144. omnibase_infra/services/session/store.py +997 -0
  145. omnibase_infra/utils/__init__.py +19 -0
  146. omnibase_infra/utils/util_atomic_file.py +261 -0
  147. omnibase_infra/utils/util_db_transaction.py +239 -0
  148. omnibase_infra/utils/util_dsn_validation.py +1 -1
  149. omnibase_infra/utils/util_retry_optimistic.py +281 -0
  150. omnibase_infra/validation/__init__.py +3 -19
  151. omnibase_infra/validation/contracts/security.validation.yaml +114 -0
  152. omnibase_infra/validation/infra_validators.py +35 -24
  153. omnibase_infra/validation/validation_exemptions.yaml +140 -9
  154. omnibase_infra/validation/validator_chain_propagation.py +2 -2
  155. omnibase_infra/validation/validator_runtime_shape.py +1 -1
  156. omnibase_infra/validation/validator_security.py +473 -370
  157. {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/METADATA +3 -3
  158. {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/RECORD +161 -98
  159. {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/WHEEL +0 -0
  160. {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/entry_points.txt +0 -0
  161. {omnibase_infra-0.2.1.dist-info → omnibase_infra-0.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,88 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry node view model for dashboard display.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from datetime import datetime
12
+ from typing import Literal
13
+ from uuid import UUID
14
+
15
+ from pydantic import BaseModel, ConfigDict, Field
16
+
17
+ from omnibase_core.models.primitives.model_semver import ModelSemVer
18
+
19
+
20
+ class ModelRegistryNodeView(BaseModel):
21
+ """Node view for dashboard display.
22
+
23
+ Represents a registered ONEX node from the registration projection,
24
+ flattened for dashboard consumption.
25
+
26
+ Attributes:
27
+ node_id: Unique identifier (entity_id from projection)
28
+ name: Human-readable node name (from service_name or node_type)
29
+ service_name: Consul service name for discovery
30
+ namespace: Optional namespace for multi-tenant deployments
31
+ display_name: Optional human-friendly display name
32
+ node_type: ONEX node archetype (EFFECT, COMPUTE, REDUCER, ORCHESTRATOR)
33
+ version: Semantic version (ModelSemVer instance)
34
+ state: Current FSM registration state
35
+ capabilities: List of capability tags
36
+ registered_at: Timestamp of initial registration
37
+ last_heartbeat_at: Timestamp of last heartbeat (nullable)
38
+ """
39
+
40
+ model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True)
41
+
42
+ node_id: UUID = Field(
43
+ ...,
44
+ description="Unique node identifier",
45
+ )
46
+ name: str = Field(
47
+ ...,
48
+ description="Node name (service_name or derived from node_type)",
49
+ )
50
+ service_name: str = Field( # ONEX_EXCLUDE: pattern - Consul discovery identifier
51
+ ...,
52
+ description="Consul service name (external Consul identifier, not entity reference)",
53
+ )
54
+ namespace: str | None = Field(
55
+ default=None,
56
+ description="Optional namespace for multi-tenant deployments",
57
+ )
58
+ display_name: str | None = Field(
59
+ default=None,
60
+ description="Optional human-friendly display name",
61
+ )
62
+ node_type: Literal["EFFECT", "COMPUTE", "REDUCER", "ORCHESTRATOR"] = Field(
63
+ ...,
64
+ description="ONEX node archetype",
65
+ )
66
+ version: ModelSemVer = Field(
67
+ ...,
68
+ description="Semantic version (ONEX standard)",
69
+ )
70
+ state: str = Field(
71
+ ...,
72
+ description="Current FSM registration state",
73
+ )
74
+ capabilities: list[str] = Field(
75
+ default_factory=list,
76
+ description="List of capability tags",
77
+ )
78
+ registered_at: datetime = Field(
79
+ ...,
80
+ description="Timestamp of initial registration",
81
+ )
82
+ last_heartbeat_at: datetime | None = Field(
83
+ default=None,
84
+ description="Timestamp of last heartbeat",
85
+ )
86
+
87
+
88
+ __all__ = ["ModelRegistryNodeView"]
@@ -0,0 +1,60 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry summary model for aggregate statistics.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pydantic import BaseModel, ConfigDict, Field
12
+
13
+
14
+ class ModelRegistrySummary(BaseModel):
15
+ """Summary statistics for the registry.
16
+
17
+ Provides aggregate counts for dashboard widgets.
18
+
19
+ Attributes:
20
+ total_nodes: Total number of registered nodes
21
+ active_nodes: Number of nodes in ACTIVE state
22
+ healthy_instances: Number of passing health check instances
23
+ unhealthy_instances: Number of failing health check instances
24
+ by_node_type: Count of nodes by type
25
+ by_state: Count of nodes by registration state
26
+ """
27
+
28
+ model_config = ConfigDict(frozen=True, extra="forbid")
29
+
30
+ total_nodes: int = Field(
31
+ ...,
32
+ ge=0,
33
+ description="Total number of registered nodes",
34
+ )
35
+ active_nodes: int = Field(
36
+ ...,
37
+ ge=0,
38
+ description="Number of nodes in ACTIVE state",
39
+ )
40
+ healthy_instances: int = Field(
41
+ ...,
42
+ ge=0,
43
+ description="Number of passing health check instances",
44
+ )
45
+ unhealthy_instances: int = Field(
46
+ ...,
47
+ ge=0,
48
+ description="Number of failing health check instances",
49
+ )
50
+ by_node_type: dict[str, int] = Field(
51
+ default_factory=dict,
52
+ description="Count of nodes by type",
53
+ )
54
+ by_state: dict[str, int] = Field(
55
+ default_factory=dict,
56
+ description="Count of nodes by registration state",
57
+ )
58
+
59
+
60
+ __all__ = ["ModelRegistrySummary"]
@@ -0,0 +1,43 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Response model for list_instances endpoint.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ - PR #182: Add Pydantic response models for API endpoints
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from pydantic import BaseModel, ConfigDict, Field
13
+
14
+ from omnibase_infra.services.registry_api.models.model_registry_instance_view import (
15
+ ModelRegistryInstanceView,
16
+ )
17
+ from omnibase_infra.services.registry_api.models.model_warning import ModelWarning
18
+
19
+
20
+ class ModelResponseListInstances(BaseModel):
21
+ """Response model for the GET /registry/instances endpoint.
22
+
23
+ Provides a list of live Consul service instances with optional warnings
24
+ for partial success scenarios.
25
+
26
+ Attributes:
27
+ instances: List of live Consul service instances
28
+ warnings: List of warnings for partial success scenarios
29
+ """
30
+
31
+ model_config = ConfigDict(frozen=True, extra="forbid")
32
+
33
+ instances: list[ModelRegistryInstanceView] = Field(
34
+ default_factory=list,
35
+ description="List of live Consul service instances",
36
+ )
37
+ warnings: list[ModelWarning] = Field(
38
+ default_factory=list,
39
+ description="Warnings for partial success scenarios",
40
+ )
41
+
42
+
43
+ __all__ = ["ModelResponseListInstances"]
@@ -0,0 +1,51 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Response model for list_nodes endpoint.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ - PR #182: Add Pydantic response models for API endpoints
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from pydantic import BaseModel, ConfigDict, Field
13
+
14
+ from omnibase_infra.services.registry_api.models.model_pagination_info import (
15
+ ModelPaginationInfo,
16
+ )
17
+ from omnibase_infra.services.registry_api.models.model_registry_node_view import (
18
+ ModelRegistryNodeView,
19
+ )
20
+ from omnibase_infra.services.registry_api.models.model_warning import ModelWarning
21
+
22
+
23
+ class ModelResponseListNodes(BaseModel):
24
+ """Response model for the GET /registry/nodes endpoint.
25
+
26
+ Provides a paginated list of registered nodes with optional warnings
27
+ for partial success scenarios.
28
+
29
+ Attributes:
30
+ nodes: List of registered nodes matching the query
31
+ pagination: Pagination information for the result set
32
+ warnings: List of warnings for partial success scenarios
33
+ """
34
+
35
+ model_config = ConfigDict(frozen=True, extra="forbid")
36
+
37
+ nodes: list[ModelRegistryNodeView] = Field(
38
+ default_factory=list,
39
+ description="List of registered nodes matching the query",
40
+ )
41
+ pagination: ModelPaginationInfo = Field(
42
+ ...,
43
+ description="Pagination information for the result set",
44
+ )
45
+ warnings: list[ModelWarning] = Field(
46
+ default_factory=list,
47
+ description="Warnings for partial success scenarios",
48
+ )
49
+
50
+
51
+ __all__ = ["ModelResponseListNodes"]
@@ -0,0 +1,49 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Warning model for partial success scenarios.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from datetime import datetime
12
+
13
+ from pydantic import BaseModel, ConfigDict, Field
14
+
15
+
16
+ class ModelWarning(BaseModel):
17
+ """Warning message for partial success scenarios.
18
+
19
+ Used when one backend succeeds but another fails, allowing the
20
+ API to return partial results with appropriate warnings.
21
+
22
+ Attributes:
23
+ source: Source of the warning (e.g., "consul", "postgres")
24
+ message: Human-readable warning message
25
+ code: Optional error code for programmatic handling
26
+ timestamp: When the warning was generated
27
+ """
28
+
29
+ model_config = ConfigDict(frozen=True, extra="forbid")
30
+
31
+ source: str = Field(
32
+ ...,
33
+ description="Source of the warning",
34
+ )
35
+ message: str = Field(
36
+ ...,
37
+ description="Human-readable warning message",
38
+ )
39
+ code: str | None = Field(
40
+ default=None,
41
+ description="Optional error code",
42
+ )
43
+ timestamp: datetime = Field(
44
+ ...,
45
+ description="When the warning was generated",
46
+ )
47
+
48
+
49
+ __all__ = ["ModelWarning"]
@@ -0,0 +1,28 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Widget defaults model for dashboard configuration.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pydantic import BaseModel, ConfigDict
12
+
13
+
14
+ class ModelWidgetDefaults(BaseModel):
15
+ """Default configuration for a widget type.
16
+
17
+ Attributes vary by widget type and provide sensible defaults.
18
+ """
19
+
20
+ model_config = ConfigDict(frozen=True, extra="allow")
21
+
22
+ # Common fields - all optional
23
+ show_timestamp: bool | None = None
24
+ max_items: int | None = None
25
+ refresh_interval_seconds: int | None = None
26
+
27
+
28
+ __all__ = ["ModelWidgetDefaults"]
@@ -0,0 +1,51 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Widget mapping model for complete dashboard configuration.
4
+
5
+ Related Tickets:
6
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pydantic import BaseModel, ConfigDict, Field
12
+
13
+ from omnibase_infra.services.registry_api.models.model_capability_widget_mapping import (
14
+ ModelCapabilityWidgetMapping,
15
+ )
16
+
17
+
18
+ class ModelWidgetMapping(BaseModel):
19
+ """Complete widget mapping configuration.
20
+
21
+ Loaded from widget_mapping.yaml, provides the mapping from
22
+ capabilities and semantic roles to widget types.
23
+
24
+ Attributes:
25
+ version: Configuration version for compatibility checking
26
+ capability_mappings: Map of capability tags to widget configs
27
+ semantic_mappings: Map of semantic roles to widget configs
28
+ fallback: Default widget config when no mapping matches
29
+ """
30
+
31
+ model_config = ConfigDict(frozen=True, extra="forbid")
32
+
33
+ version: str = Field(
34
+ ...,
35
+ description="Configuration version",
36
+ )
37
+ capability_mappings: dict[str, ModelCapabilityWidgetMapping] = Field(
38
+ default_factory=dict,
39
+ description="Map of capability tags to widget configs",
40
+ )
41
+ semantic_mappings: dict[str, ModelCapabilityWidgetMapping] = Field(
42
+ default_factory=dict,
43
+ description="Map of semantic roles to widget configs",
44
+ )
45
+ fallback: ModelCapabilityWidgetMapping = Field(
46
+ ...,
47
+ description="Default widget config when no mapping matches",
48
+ )
49
+
50
+
51
+ __all__ = ["ModelWidgetMapping"]