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,261 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry API FastAPI Application.
4
+
5
+ Creates and configures the FastAPI application for the Registry API.
6
+ Provides factory function for flexible instantiation with different
7
+ backend configurations.
8
+
9
+ Usage:
10
+ # Create app with container (required)
11
+ from omnibase_core.container import ModelONEXContainer
12
+
13
+ container = ModelONEXContainer()
14
+ app = create_app(container=container, cors_origins=["http://localhost:3000"])
15
+
16
+ # Create app with full backends
17
+ app = create_app(
18
+ container=container,
19
+ projection_reader=reader,
20
+ consul_handler=handler,
21
+ cors_origins=["http://localhost:3000"],
22
+ )
23
+
24
+ # Run with uvicorn
25
+ uvicorn.run(app, host="0.0.0.0", port=8000)
26
+
27
+ Related Tickets:
28
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import logging
34
+ import os
35
+ from collections.abc import AsyncIterator
36
+ from contextlib import asynccontextmanager
37
+ from pathlib import Path
38
+ from typing import TYPE_CHECKING
39
+
40
+ from fastapi import FastAPI
41
+ from fastapi.middleware.cors import CORSMiddleware
42
+
43
+ from omnibase_core.container import ModelONEXContainer
44
+ from omnibase_infra.enums import EnumInfraTransportType
45
+ from omnibase_infra.errors import ModelInfraErrorContext, ProtocolConfigurationError
46
+ from omnibase_infra.services.registry_api.routes import router
47
+ from omnibase_infra.services.registry_api.service import ServiceRegistryDiscovery
48
+
49
+ if TYPE_CHECKING:
50
+ from omnibase_infra.handlers.service_discovery import HandlerServiceDiscoveryConsul
51
+ from omnibase_infra.projectors import ProjectionReaderRegistration
52
+
53
+ logger = logging.getLogger(__name__)
54
+
55
+ # API metadata
56
+ API_TITLE = "ONEX Registry API"
57
+ API_DESCRIPTION = """
58
+ Registry Discovery API for ONEX Dashboard Integration.
59
+
60
+ This API provides access to node registrations and live service instances
61
+ for dashboard consumption. It combines data from:
62
+
63
+ - **PostgreSQL Projections**: Node registration state, capabilities, and metadata
64
+ - **Consul Service Discovery**: Live service instances with health status
65
+
66
+ ## Key Features
67
+
68
+ - **Full Dashboard Payload**: Single endpoint for all dashboard data
69
+ - **Partial Success**: Returns data even when one backend fails
70
+ - **Widget Mapping**: Configuration for capability-to-widget rendering
71
+ - **Health Monitoring**: Component-level health status
72
+
73
+ ## Related Tickets
74
+
75
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
76
+ """
77
+ API_VERSION = "1.0.0"
78
+
79
+
80
+ @asynccontextmanager
81
+ async def lifespan(app: FastAPI) -> AsyncIterator[None]:
82
+ """Application lifespan handler for startup/shutdown.
83
+
84
+ Initializes backend connections on startup and cleans up on shutdown.
85
+
86
+ Args:
87
+ app: FastAPI application instance.
88
+
89
+ Yields:
90
+ None (context manager pattern).
91
+ """
92
+ logger.info("Registry API starting up")
93
+
94
+ # Log configuration
95
+ service: ServiceRegistryDiscovery | None = getattr(
96
+ app.state, "registry_service", None
97
+ )
98
+ if service is not None:
99
+ logger.info(
100
+ "Registry service configured",
101
+ extra={
102
+ "has_projection_reader": service.has_projection_reader,
103
+ "has_consul_handler": service.has_consul_handler,
104
+ },
105
+ )
106
+ else:
107
+ logger.warning("Registry service not configured - API will return limited data")
108
+
109
+ yield
110
+
111
+ logger.info("Registry API shutting down")
112
+
113
+ # Cleanup Consul handler if we own it
114
+ if service is not None and service.consul_handler is not None:
115
+ try:
116
+ await service.consul_handler.shutdown()
117
+ logger.info("Consul handler shutdown complete")
118
+ except Exception as e:
119
+ logger.exception(
120
+ "Error during Consul handler shutdown",
121
+ extra={"error_type": type(e).__name__},
122
+ )
123
+
124
+
125
+ def create_app(
126
+ container: ModelONEXContainer,
127
+ projection_reader: ProjectionReaderRegistration | None = None,
128
+ consul_handler: HandlerServiceDiscoveryConsul | None = None,
129
+ widget_mapping_path: Path | None = None,
130
+ cors_origins: list[str] | None = None,
131
+ ) -> FastAPI:
132
+ """Create and configure the Registry API FastAPI application.
133
+
134
+ Factory function that creates a FastAPI app with the specified
135
+ backend configurations. All backends are optional - the API will
136
+ return partial data with warnings when backends are unavailable.
137
+
138
+ Args:
139
+ container: ONEX container for dependency injection. Required for
140
+ ONEX DI pattern compliance.
141
+ projection_reader: Optional projection reader for node registrations.
142
+ consul_handler: Optional Consul handler for live instances.
143
+ widget_mapping_path: Optional path to widget mapping YAML.
144
+ cors_origins: Optional list of allowed CORS origins.
145
+ If not provided, reads from CORS_ORIGINS environment variable.
146
+ Raises ProtocolConfigurationError if neither is configured (fail-fast).
147
+
148
+ Returns:
149
+ Configured FastAPI application.
150
+
151
+ Raises:
152
+ ProtocolConfigurationError: If CORS origins not configured via parameter
153
+ or CORS_ORIGINS environment variable.
154
+
155
+ Example:
156
+ >>> from omnibase_infra.services.registry_api import create_app
157
+ >>> from omnibase_core.container import ModelONEXContainer
158
+ >>> container = ModelONEXContainer()
159
+ >>> app = create_app(container=container)
160
+ >>> # Run with: uvicorn module:app --host 0.0.0.0 --port 8000
161
+ """
162
+ app = FastAPI(
163
+ title=API_TITLE,
164
+ description=API_DESCRIPTION,
165
+ version=API_VERSION,
166
+ lifespan=lifespan,
167
+ docs_url="/docs",
168
+ redoc_url="/redoc",
169
+ openapi_url="/openapi.json",
170
+ )
171
+
172
+ # Configure CORS - fail-fast if not configured
173
+ if cors_origins is not None:
174
+ origins = cors_origins
175
+ else:
176
+ env_origins = os.environ.get("CORS_ORIGINS")
177
+ if env_origins is None:
178
+ context = ModelInfraErrorContext.with_correlation(
179
+ transport_type=EnumInfraTransportType.HTTP,
180
+ operation="configure_cors",
181
+ )
182
+ raise ProtocolConfigurationError(
183
+ "CORS_ORIGINS must be configured. "
184
+ "Set the CORS_ORIGINS environment variable (comma-separated list of allowed origins) "
185
+ "or pass cors_origins parameter to create_app(). "
186
+ "Example: CORS_ORIGINS=http://localhost:3000,https://dashboard.example.com",
187
+ context=context,
188
+ )
189
+ origins = env_origins.split(",")
190
+
191
+ # Warn about wildcard CORS - only when explicitly configured
192
+ if "*" in origins:
193
+ logger.warning(
194
+ "CORS explicitly configured with wildcard origin '*'. "
195
+ "This is acceptable for development but should be restricted in production.",
196
+ extra={"origins": origins},
197
+ )
198
+
199
+ app.add_middleware(
200
+ CORSMiddleware,
201
+ allow_origins=origins,
202
+ allow_credentials=True,
203
+ allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
204
+ allow_headers=["*"],
205
+ )
206
+
207
+ # Create and attach service
208
+ service = ServiceRegistryDiscovery(
209
+ container=container,
210
+ projection_reader=projection_reader,
211
+ consul_handler=consul_handler,
212
+ widget_mapping_path=widget_mapping_path,
213
+ )
214
+ app.state.registry_service = service
215
+
216
+ # Include routes
217
+ app.include_router(router)
218
+
219
+ # Root endpoint
220
+ @app.get("/", include_in_schema=False)
221
+ async def root() -> dict[str, str]:
222
+ """Root endpoint with API info."""
223
+ return {
224
+ "service": API_TITLE,
225
+ "version": API_VERSION,
226
+ "docs": "/docs",
227
+ "health": "/registry/health",
228
+ }
229
+
230
+ logger.info(
231
+ "Registry API created",
232
+ extra={
233
+ "version": API_VERSION,
234
+ "cors_origins": origins,
235
+ },
236
+ )
237
+
238
+ return app
239
+
240
+
241
+ # Module-level app instance is not supported since container is required.
242
+ # For production usage, use create_app() with proper configuration:
243
+ #
244
+ # Example:
245
+ # from omnibase_core.container import ModelONEXContainer
246
+ # from omnibase_infra.services.registry_api import create_app
247
+ #
248
+ # container = ModelONEXContainer()
249
+ # app = create_app(
250
+ # container=container,
251
+ # projection_reader=reader,
252
+ # consul_handler=handler,
253
+ # cors_origins=["http://localhost:3000"],
254
+ # )
255
+ # uvicorn.run(app, host="0.0.0.0", port=8000)
256
+ #
257
+ # For uvicorn CLI usage, create a launcher module that instantiates the container.
258
+ app: FastAPI | None = None
259
+
260
+
261
+ __all__ = ["app", "create_app"]
@@ -0,0 +1,66 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry API Response Models.
4
+
5
+ Pydantic models for the Registry API HTTP responses. These models define
6
+ the JSON shape returned by each endpoint for dashboard consumption.
7
+
8
+ Design Principles:
9
+ - Flat, dashboard-friendly structures (no deep nesting)
10
+ - Explicit field descriptions for API documentation
11
+ - Immutable (frozen) for thread safety
12
+ - Strict validation (extra="forbid")
13
+
14
+ Related Tickets:
15
+ - OMN-1278: Contract-Driven Dashboard - Registry Discovery
16
+ """
17
+
18
+ from omnibase_infra.services.registry_api.models.model_capability_widget_mapping import (
19
+ ModelCapabilityWidgetMapping,
20
+ )
21
+ from omnibase_infra.services.registry_api.models.model_pagination_info import (
22
+ ModelPaginationInfo,
23
+ )
24
+ from omnibase_infra.services.registry_api.models.model_registry_discovery_response import (
25
+ ModelRegistryDiscoveryResponse,
26
+ )
27
+ from omnibase_infra.services.registry_api.models.model_registry_health_response import (
28
+ ModelRegistryHealthResponse,
29
+ )
30
+ from omnibase_infra.services.registry_api.models.model_registry_instance_view import (
31
+ ModelRegistryInstanceView,
32
+ )
33
+ from omnibase_infra.services.registry_api.models.model_registry_node_view import (
34
+ ModelRegistryNodeView,
35
+ )
36
+ from omnibase_infra.services.registry_api.models.model_registry_summary import (
37
+ ModelRegistrySummary,
38
+ )
39
+ from omnibase_infra.services.registry_api.models.model_response_list_instances import (
40
+ ModelResponseListInstances,
41
+ )
42
+ from omnibase_infra.services.registry_api.models.model_response_list_nodes import (
43
+ ModelResponseListNodes,
44
+ )
45
+ from omnibase_infra.services.registry_api.models.model_warning import ModelWarning
46
+ from omnibase_infra.services.registry_api.models.model_widget_defaults import (
47
+ ModelWidgetDefaults,
48
+ )
49
+ from omnibase_infra.services.registry_api.models.model_widget_mapping import (
50
+ ModelWidgetMapping,
51
+ )
52
+
53
+ __all__ = [
54
+ "ModelCapabilityWidgetMapping",
55
+ "ModelPaginationInfo",
56
+ "ModelRegistryDiscoveryResponse",
57
+ "ModelRegistryHealthResponse",
58
+ "ModelRegistryInstanceView",
59
+ "ModelRegistryNodeView",
60
+ "ModelRegistrySummary",
61
+ "ModelResponseListInstances",
62
+ "ModelResponseListNodes",
63
+ "ModelWarning",
64
+ "ModelWidgetDefaults",
65
+ "ModelWidgetMapping",
66
+ ]
@@ -0,0 +1,38 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Capability widget mapping 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, Field
12
+
13
+ from omnibase_infra.services.registry_api.models.model_widget_defaults import (
14
+ ModelWidgetDefaults,
15
+ )
16
+
17
+
18
+ class ModelCapabilityWidgetMapping(BaseModel):
19
+ """Mapping from a capability to its widget configuration.
20
+
21
+ Attributes:
22
+ widget_type: Type of widget to render
23
+ defaults: Default widget configuration
24
+ """
25
+
26
+ model_config = ConfigDict(frozen=True, extra="forbid")
27
+
28
+ widget_type: str = Field(
29
+ ...,
30
+ description="Type of widget to render",
31
+ )
32
+ defaults: ModelWidgetDefaults = Field(
33
+ default_factory=ModelWidgetDefaults,
34
+ description="Default widget configuration",
35
+ )
36
+
37
+
38
+ __all__ = ["ModelCapabilityWidgetMapping"]
@@ -0,0 +1,48 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Pagination info model for list endpoints.
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 ModelPaginationInfo(BaseModel):
15
+ """Pagination information for list endpoints.
16
+
17
+ Attributes:
18
+ total: Total number of items matching the query
19
+ limit: Maximum items per page
20
+ offset: Current offset (0-based)
21
+ has_more: Whether more items exist beyond current page
22
+ """
23
+
24
+ model_config = ConfigDict(frozen=True, extra="forbid")
25
+
26
+ total: int = Field(
27
+ ...,
28
+ ge=0,
29
+ description="Total number of items",
30
+ )
31
+ limit: int = Field(
32
+ ...,
33
+ ge=1,
34
+ le=1000,
35
+ description="Maximum items per page",
36
+ )
37
+ offset: int = Field(
38
+ ...,
39
+ ge=0,
40
+ description="Current offset (0-based)",
41
+ )
42
+ has_more: bool = Field(
43
+ ...,
44
+ description="Whether more items exist",
45
+ )
46
+
47
+
48
+ __all__ = ["ModelPaginationInfo"]
@@ -0,0 +1,73 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry discovery response model for dashboard payload.
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
+ from omnibase_infra.services.registry_api.models.model_pagination_info import (
16
+ ModelPaginationInfo,
17
+ )
18
+ from omnibase_infra.services.registry_api.models.model_registry_instance_view import (
19
+ ModelRegistryInstanceView,
20
+ )
21
+ from omnibase_infra.services.registry_api.models.model_registry_node_view import (
22
+ ModelRegistryNodeView,
23
+ )
24
+ from omnibase_infra.services.registry_api.models.model_registry_summary import (
25
+ ModelRegistrySummary,
26
+ )
27
+ from omnibase_infra.services.registry_api.models.model_warning import ModelWarning
28
+
29
+
30
+ class ModelRegistryDiscoveryResponse(BaseModel):
31
+ """Full dashboard payload combining nodes, instances, and summary.
32
+
33
+ The primary response model for the GET /registry/discovery endpoint,
34
+ providing everything a dashboard needs in a single request.
35
+
36
+ Attributes:
37
+ timestamp: When this response was generated
38
+ warnings: List of warnings for partial success scenarios
39
+ summary: Aggregate statistics
40
+ nodes: List of registered nodes
41
+ live_instances: List of live Consul instances
42
+ pagination: Pagination info for nodes list
43
+ """
44
+
45
+ model_config = ConfigDict(frozen=True, extra="forbid")
46
+
47
+ timestamp: datetime = Field(
48
+ ...,
49
+ description="When this response was generated",
50
+ )
51
+ warnings: list[ModelWarning] = Field(
52
+ default_factory=list,
53
+ description="Warnings for partial success scenarios",
54
+ )
55
+ summary: ModelRegistrySummary = Field(
56
+ ...,
57
+ description="Aggregate statistics",
58
+ )
59
+ nodes: list[ModelRegistryNodeView] = Field(
60
+ default_factory=list,
61
+ description="List of registered nodes",
62
+ )
63
+ live_instances: list[ModelRegistryInstanceView] = Field(
64
+ default_factory=list,
65
+ description="List of live Consul instances",
66
+ )
67
+ pagination: ModelPaginationInfo = Field(
68
+ ...,
69
+ description="Pagination info for nodes list",
70
+ )
71
+
72
+
73
+ __all__ = ["ModelRegistryDiscoveryResponse"]
@@ -0,0 +1,49 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry health response model for API health checks.
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
+
14
+ from pydantic import BaseModel, ConfigDict, Field
15
+
16
+ from omnibase_core.types import JsonType
17
+
18
+
19
+ class ModelRegistryHealthResponse(BaseModel):
20
+ """Health check response for the registry API.
21
+
22
+ Attributes:
23
+ status: Overall health status (healthy, degraded, unhealthy)
24
+ timestamp: When the health check was performed
25
+ components: Health status of individual components
26
+ version: API version string
27
+ """
28
+
29
+ model_config = ConfigDict(frozen=True, extra="forbid")
30
+
31
+ status: Literal["healthy", "degraded", "unhealthy"] = Field(
32
+ ...,
33
+ description="Overall health status",
34
+ )
35
+ timestamp: datetime = Field(
36
+ ...,
37
+ description="When the health check was performed",
38
+ )
39
+ components: dict[str, JsonType] = Field(
40
+ default_factory=dict,
41
+ description="Health status of individual components",
42
+ )
43
+ version: str = Field(
44
+ default="1.0.0",
45
+ description="API version string",
46
+ )
47
+
48
+
49
+ __all__ = ["ModelRegistryHealthResponse"]
@@ -0,0 +1,88 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Registry instance 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
+
18
+ class ModelRegistryInstanceView(BaseModel):
19
+ """Live service instance view for dashboard display.
20
+
21
+ Represents a live Consul service instance, providing real-time
22
+ health and connectivity information.
23
+
24
+ Attributes:
25
+ node_id: Node UUID (may be derived from service_id if not UUID)
26
+ service_name: Consul service name
27
+ service_id: Consul service instance ID
28
+ instance_id: Unique instance identifier (same as service_id)
29
+ address: Network address (IP or hostname)
30
+ port: Service port number
31
+ health_status: Health check status (passing, warning, critical, unknown)
32
+ health_output: Health check output message (nullable)
33
+ last_check_at: Timestamp of last health check (nullable)
34
+ tags: Consul service tags
35
+ meta: Consul service metadata
36
+ """
37
+
38
+ model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True)
39
+
40
+ node_id: UUID = Field(
41
+ ...,
42
+ description="Node UUID (may be derived from service_id)",
43
+ )
44
+ service_name: str = Field( # ONEX_EXCLUDE: pattern - Consul discovery identifier
45
+ ...,
46
+ description="Consul service name (external Consul identifier, not entity reference)",
47
+ )
48
+ service_id: UUID = Field(
49
+ ...,
50
+ description="Consul service instance ID",
51
+ )
52
+ instance_id: UUID = Field(
53
+ ...,
54
+ description="Unique instance identifier",
55
+ )
56
+ address: str = Field(
57
+ ...,
58
+ description="Network address (IP or hostname)",
59
+ )
60
+ port: int = Field(
61
+ ...,
62
+ ge=1,
63
+ le=65535,
64
+ description="Service port number",
65
+ )
66
+ health_status: Literal["passing", "warning", "critical", "unknown"] = Field(
67
+ ...,
68
+ description="Health check status",
69
+ )
70
+ health_output: str | None = Field(
71
+ default=None,
72
+ description="Health check output message",
73
+ )
74
+ last_check_at: datetime | None = Field(
75
+ default=None,
76
+ description="Timestamp of last health check",
77
+ )
78
+ tags: list[str] = Field(
79
+ default_factory=list,
80
+ description="Consul service tags",
81
+ )
82
+ meta: dict[str, str] = Field(
83
+ default_factory=dict,
84
+ description="Consul service metadata",
85
+ )
86
+
87
+
88
+ __all__ = ["ModelRegistryInstanceView"]