omnibase_infra 0.2.6__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 (833) hide show
  1. omnibase_infra/__init__.py +101 -0
  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/__init__.py +1 -0
  8. omnibase_infra/cli/commands.py +216 -0
  9. omnibase_infra/clients/__init__.py +0 -0
  10. omnibase_infra/configs/widget_mapping.yaml +176 -0
  11. omnibase_infra/constants_topic_patterns.py +26 -0
  12. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
  13. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -0
  14. omnibase_infra/decorators/__init__.py +29 -0
  15. omnibase_infra/decorators/allow_any.py +109 -0
  16. omnibase_infra/dlq/__init__.py +90 -0
  17. omnibase_infra/dlq/constants_dlq.py +57 -0
  18. omnibase_infra/dlq/models/__init__.py +26 -0
  19. omnibase_infra/dlq/models/enum_replay_status.py +37 -0
  20. omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
  21. omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
  22. omnibase_infra/dlq/service_dlq_tracking.py +611 -0
  23. omnibase_infra/enums/__init__.py +132 -0
  24. omnibase_infra/enums/enum_any_type_violation.py +104 -0
  25. omnibase_infra/enums/enum_backend_type.py +27 -0
  26. omnibase_infra/enums/enum_capture_outcome.py +42 -0
  27. omnibase_infra/enums/enum_capture_state.py +88 -0
  28. omnibase_infra/enums/enum_chain_violation_type.py +119 -0
  29. omnibase_infra/enums/enum_circuit_state.py +51 -0
  30. omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
  31. omnibase_infra/enums/enum_consumer_group_purpose.py +92 -0
  32. omnibase_infra/enums/enum_contract_type.py +84 -0
  33. omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
  34. omnibase_infra/enums/enum_dispatch_status.py +191 -0
  35. omnibase_infra/enums/enum_environment.py +46 -0
  36. omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
  37. omnibase_infra/enums/enum_handler_error_type.py +111 -0
  38. omnibase_infra/enums/enum_handler_loader_error.py +178 -0
  39. omnibase_infra/enums/enum_handler_source_mode.py +86 -0
  40. omnibase_infra/enums/enum_handler_source_type.py +87 -0
  41. omnibase_infra/enums/enum_handler_type.py +77 -0
  42. omnibase_infra/enums/enum_handler_type_category.py +61 -0
  43. omnibase_infra/enums/enum_infra_transport_type.py +73 -0
  44. omnibase_infra/enums/enum_introspection_reason.py +154 -0
  45. omnibase_infra/enums/enum_kafka_acks.py +99 -0
  46. omnibase_infra/enums/enum_message_category.py +213 -0
  47. omnibase_infra/enums/enum_node_archetype.py +74 -0
  48. omnibase_infra/enums/enum_node_output_type.py +185 -0
  49. omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
  50. omnibase_infra/enums/enum_policy_type.py +32 -0
  51. omnibase_infra/enums/enum_registration_state.py +261 -0
  52. omnibase_infra/enums/enum_registration_status.py +33 -0
  53. omnibase_infra/enums/enum_registry_response_status.py +28 -0
  54. omnibase_infra/enums/enum_response_status.py +26 -0
  55. omnibase_infra/enums/enum_retry_error_category.py +98 -0
  56. omnibase_infra/enums/enum_security_rule_id.py +103 -0
  57. omnibase_infra/enums/enum_selection_strategy.py +91 -0
  58. omnibase_infra/enums/enum_topic_standard.py +42 -0
  59. omnibase_infra/enums/enum_validation_severity.py +78 -0
  60. omnibase_infra/errors/__init__.py +160 -0
  61. omnibase_infra/errors/error_architecture_violation.py +152 -0
  62. omnibase_infra/errors/error_binding_resolution.py +128 -0
  63. omnibase_infra/errors/error_chain_propagation.py +188 -0
  64. omnibase_infra/errors/error_compute_registry.py +95 -0
  65. omnibase_infra/errors/error_consul.py +132 -0
  66. omnibase_infra/errors/error_container_wiring.py +243 -0
  67. omnibase_infra/errors/error_event_bus_registry.py +105 -0
  68. omnibase_infra/errors/error_infra.py +610 -0
  69. omnibase_infra/errors/error_message_type_registry.py +101 -0
  70. omnibase_infra/errors/error_policy_registry.py +115 -0
  71. omnibase_infra/errors/error_vault.py +123 -0
  72. omnibase_infra/event_bus/__init__.py +72 -0
  73. omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +84 -0
  74. omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
  75. omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
  76. omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
  77. omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -0
  78. omnibase_infra/event_bus/models/__init__.py +29 -0
  79. omnibase_infra/event_bus/models/config/__init__.py +20 -0
  80. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +693 -0
  81. omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
  82. omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
  83. omnibase_infra/event_bus/models/model_event_headers.py +115 -0
  84. omnibase_infra/event_bus/models/model_event_message.py +60 -0
  85. omnibase_infra/event_bus/testing/__init__.py +26 -0
  86. omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
  87. omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
  88. omnibase_infra/event_bus/topic_constants.py +376 -0
  89. omnibase_infra/handlers/__init__.py +82 -0
  90. omnibase_infra/handlers/filesystem/__init__.py +48 -0
  91. omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
  92. omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
  93. omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
  94. omnibase_infra/handlers/handler_consul.py +795 -0
  95. omnibase_infra/handlers/handler_db.py +1046 -0
  96. omnibase_infra/handlers/handler_filesystem.py +1478 -0
  97. omnibase_infra/handlers/handler_graph.py +2015 -0
  98. omnibase_infra/handlers/handler_http.py +926 -0
  99. omnibase_infra/handlers/handler_intent.py +387 -0
  100. omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
  101. omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
  102. omnibase_infra/handlers/handler_mcp.py +1430 -0
  103. omnibase_infra/handlers/handler_qdrant.py +1076 -0
  104. omnibase_infra/handlers/handler_vault.py +428 -0
  105. omnibase_infra/handlers/mcp/__init__.py +19 -0
  106. omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
  107. omnibase_infra/handlers/mcp/protocols.py +178 -0
  108. omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
  109. omnibase_infra/handlers/mixins/__init__.py +47 -0
  110. omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
  111. omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
  112. omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
  113. omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -0
  114. omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
  115. omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
  116. omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
  117. omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
  118. omnibase_infra/handlers/models/__init__.py +286 -0
  119. omnibase_infra/handlers/models/consul/__init__.py +81 -0
  120. omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
  121. omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
  122. omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
  123. omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
  124. omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
  125. omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
  126. omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
  127. omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
  128. omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
  129. omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
  130. omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
  131. omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
  132. omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
  133. omnibase_infra/handlers/models/graph/__init__.py +35 -0
  134. omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
  135. omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
  136. omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
  137. omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
  138. omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
  139. omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
  140. omnibase_infra/handlers/models/http/__init__.py +50 -0
  141. omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
  142. omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
  143. omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
  144. omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
  145. omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
  146. omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
  147. omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
  148. omnibase_infra/handlers/models/mcp/__init__.py +23 -0
  149. omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
  150. omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
  151. omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
  152. omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
  153. omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
  154. omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
  155. omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
  156. omnibase_infra/handlers/models/model_db_query_response.py +60 -0
  157. omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
  158. omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
  159. omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
  160. omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
  161. omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
  162. omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
  163. omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
  164. omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
  165. omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
  166. omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
  167. omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
  168. omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
  169. omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
  170. omnibase_infra/handlers/models/model_handler_response.py +103 -0
  171. omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
  172. omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
  173. omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
  174. omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
  175. omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
  176. omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
  177. omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
  178. omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
  179. omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
  180. omnibase_infra/handlers/models/model_operation_context.py +187 -0
  181. omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
  182. omnibase_infra/handlers/models/model_retry_state.py +162 -0
  183. omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
  184. omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
  185. omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
  186. omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
  187. omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
  188. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
  189. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
  190. omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
  191. omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
  192. omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
  193. omnibase_infra/handlers/models/vault/__init__.py +69 -0
  194. omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
  195. omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
  196. omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
  197. omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
  198. omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
  199. omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
  200. omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
  201. omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
  202. omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
  203. omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
  204. omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
  205. omnibase_infra/handlers/registration_storage/__init__.py +43 -0
  206. omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
  207. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +922 -0
  208. omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
  209. omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
  210. omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
  211. omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
  212. omnibase_infra/handlers/service_discovery/__init__.py +43 -0
  213. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +1051 -0
  214. omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
  215. omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
  216. omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
  217. omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
  218. omnibase_infra/handlers/service_discovery/models/model_service_info.py +109 -0
  219. omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
  220. omnibase_infra/idempotency/__init__.py +94 -0
  221. omnibase_infra/idempotency/models/__init__.py +43 -0
  222. omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
  223. omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
  224. omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
  225. omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
  226. omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
  227. omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
  228. omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
  229. omnibase_infra/idempotency/store_inmemory.py +265 -0
  230. omnibase_infra/idempotency/store_postgres.py +923 -0
  231. omnibase_infra/infrastructure/__init__.py +0 -0
  232. omnibase_infra/migrations/001_create_event_ledger.sql +166 -0
  233. omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
  234. omnibase_infra/mixins/__init__.py +71 -0
  235. omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -0
  236. omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
  237. omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
  238. omnibase_infra/mixins/mixin_node_introspection.py +2670 -0
  239. omnibase_infra/mixins/mixin_retry_execution.py +386 -0
  240. omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
  241. omnibase_infra/models/__init__.py +144 -0
  242. omnibase_infra/models/bindings/__init__.py +59 -0
  243. omnibase_infra/models/bindings/constants.py +144 -0
  244. omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
  245. omnibase_infra/models/bindings/model_operation_binding.py +44 -0
  246. omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
  247. omnibase_infra/models/bindings/model_parsed_binding.py +52 -0
  248. omnibase_infra/models/corpus/__init__.py +17 -0
  249. omnibase_infra/models/corpus/model_capture_config.py +133 -0
  250. omnibase_infra/models/corpus/model_capture_result.py +86 -0
  251. omnibase_infra/models/discovery/__init__.py +42 -0
  252. omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
  253. omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
  254. omnibase_infra/models/discovery/model_introspection_config.py +330 -0
  255. omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
  256. omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
  257. omnibase_infra/models/dispatch/__init__.py +155 -0
  258. omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -0
  259. omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
  260. omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
  261. omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
  262. omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
  263. omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
  264. omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
  265. omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
  266. omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
  267. omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
  268. omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
  269. omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
  270. omnibase_infra/models/dispatch/model_materialized_dispatch.py +141 -0
  271. omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
  272. omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
  273. omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
  274. omnibase_infra/models/errors/__init__.py +45 -0
  275. omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
  276. omnibase_infra/models/errors/model_infra_error_context.py +99 -0
  277. omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
  278. omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
  279. omnibase_infra/models/handlers/__init__.py +80 -0
  280. omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
  281. omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
  282. omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
  283. omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
  284. omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
  285. omnibase_infra/models/health/__init__.py +9 -0
  286. omnibase_infra/models/health/model_health_check_result.py +40 -0
  287. omnibase_infra/models/lifecycle/__init__.py +39 -0
  288. omnibase_infra/models/logging/__init__.py +51 -0
  289. omnibase_infra/models/logging/model_log_context.py +756 -0
  290. omnibase_infra/models/mcp/__init__.py +15 -0
  291. omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
  292. omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
  293. omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
  294. omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
  295. omnibase_infra/models/model_node_identity.py +126 -0
  296. omnibase_infra/models/model_retry_error_classification.py +78 -0
  297. omnibase_infra/models/projection/__init__.py +43 -0
  298. omnibase_infra/models/projection/model_capability_fields.py +112 -0
  299. omnibase_infra/models/projection/model_registration_projection.py +434 -0
  300. omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
  301. omnibase_infra/models/projection/model_sequence_info.py +182 -0
  302. omnibase_infra/models/projection/model_snapshot_topic_config.py +591 -0
  303. omnibase_infra/models/projectors/__init__.py +41 -0
  304. omnibase_infra/models/projectors/model_projector_column.py +289 -0
  305. omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
  306. omnibase_infra/models/projectors/model_projector_index.py +270 -0
  307. omnibase_infra/models/projectors/model_projector_schema.py +415 -0
  308. omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
  309. omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
  310. omnibase_infra/models/registration/__init__.py +68 -0
  311. omnibase_infra/models/registration/commands/__init__.py +15 -0
  312. omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
  313. omnibase_infra/models/registration/events/__init__.py +56 -0
  314. omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
  315. omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
  316. omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
  317. omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
  318. omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
  319. omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
  320. omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
  321. omnibase_infra/models/registration/model_event_bus_topic_entry.py +59 -0
  322. omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
  323. omnibase_infra/models/registration/model_node_capabilities.py +190 -0
  324. omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
  325. omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
  326. omnibase_infra/models/registration/model_node_introspection_event.py +195 -0
  327. omnibase_infra/models/registration/model_node_metadata.py +79 -0
  328. omnibase_infra/models/registration/model_node_registration.py +162 -0
  329. omnibase_infra/models/registration/model_node_registration_record.py +162 -0
  330. omnibase_infra/models/registry/__init__.py +29 -0
  331. omnibase_infra/models/registry/model_domain_constraint.py +202 -0
  332. omnibase_infra/models/registry/model_message_type_entry.py +271 -0
  333. omnibase_infra/models/resilience/__init__.py +9 -0
  334. omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
  335. omnibase_infra/models/routing/__init__.py +25 -0
  336. omnibase_infra/models/routing/model_routing_entry.py +52 -0
  337. omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
  338. omnibase_infra/models/runtime/__init__.py +49 -0
  339. omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
  340. omnibase_infra/models/runtime/model_discovery_error.py +81 -0
  341. omnibase_infra/models/runtime/model_discovery_result.py +162 -0
  342. omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
  343. omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
  344. omnibase_infra/models/runtime/model_handler_contract.py +296 -0
  345. omnibase_infra/models/runtime/model_loaded_handler.py +129 -0
  346. omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
  347. omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
  348. omnibase_infra/models/security/__init__.py +50 -0
  349. omnibase_infra/models/security/classification_levels.py +99 -0
  350. omnibase_infra/models/security/model_environment_policy.py +145 -0
  351. omnibase_infra/models/security/model_handler_security_policy.py +107 -0
  352. omnibase_infra/models/security/model_security_error.py +81 -0
  353. omnibase_infra/models/security/model_security_validation_result.py +328 -0
  354. omnibase_infra/models/security/model_security_warning.py +67 -0
  355. omnibase_infra/models/snapshot/__init__.py +27 -0
  356. omnibase_infra/models/snapshot/model_field_change.py +65 -0
  357. omnibase_infra/models/snapshot/model_snapshot.py +270 -0
  358. omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
  359. omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
  360. omnibase_infra/models/types/__init__.py +71 -0
  361. omnibase_infra/models/validation/__init__.py +89 -0
  362. omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
  363. omnibase_infra/models/validation/model_any_type_violation.py +141 -0
  364. omnibase_infra/models/validation/model_category_match_result.py +345 -0
  365. omnibase_infra/models/validation/model_chain_violation.py +166 -0
  366. omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
  367. omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
  368. omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
  369. omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
  370. omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
  371. omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
  372. omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
  373. omnibase_infra/models/validation/model_output_validation_params.py +74 -0
  374. omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
  375. omnibase_infra/models/validation/model_validation_error_params.py +84 -0
  376. omnibase_infra/models/validation/model_validation_outcome.py +287 -0
  377. omnibase_infra/nodes/__init__.py +57 -0
  378. omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
  379. omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
  380. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +203 -0
  381. omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
  382. omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
  383. omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
  384. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
  385. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
  386. omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
  387. omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
  388. omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
  389. omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
  390. omnibase_infra/nodes/architecture_validator/node.py +262 -0
  391. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
  392. omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
  393. omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
  394. omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
  395. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +106 -0
  396. omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
  397. omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
  398. omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
  399. omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
  400. omnibase_infra/nodes/contract_registry_reducer/__init__.py +29 -0
  401. omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
  402. omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
  403. omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
  404. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
  405. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
  406. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
  407. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
  408. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
  409. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
  410. omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
  411. omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
  412. omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
  413. omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
  414. omnibase_infra/nodes/effects/README.md +358 -0
  415. omnibase_infra/nodes/effects/__init__.py +26 -0
  416. omnibase_infra/nodes/effects/contract.yaml +167 -0
  417. omnibase_infra/nodes/effects/models/__init__.py +32 -0
  418. omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
  419. omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
  420. omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
  421. omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
  422. omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
  423. omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
  424. omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
  425. omnibase_infra/nodes/effects/registry_effect.py +525 -0
  426. omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
  427. omnibase_infra/nodes/handlers/consul/contract.yaml +85 -0
  428. omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
  429. omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
  430. omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
  431. omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
  432. omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
  433. omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
  434. omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
  435. omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
  436. omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
  437. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
  438. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
  439. omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
  440. omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
  441. omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
  442. omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
  443. omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
  444. omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
  445. omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
  446. omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
  447. omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
  448. omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
  449. omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
  450. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
  451. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
  452. omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
  453. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
  454. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
  455. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
  456. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
  457. omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
  458. omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
  459. omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
  460. omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
  461. omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -0
  462. omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
  463. omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
  464. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +482 -0
  465. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
  466. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
  467. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
  468. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
  469. omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
  470. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
  471. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +694 -0
  472. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
  473. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
  474. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
  475. omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
  476. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
  477. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
  478. omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
  479. omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
  480. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
  481. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
  482. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
  483. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
  484. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
  485. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
  486. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
  487. omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
  488. omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
  489. omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
  490. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
  491. omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
  492. omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
  493. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +528 -0
  494. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
  495. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -0
  496. omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
  497. omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
  498. omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
  499. omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
  500. omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
  501. omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
  502. omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
  503. omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
  504. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +220 -0
  505. omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
  506. omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
  507. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
  508. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
  509. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
  510. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
  511. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
  512. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
  513. omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
  514. omnibase_infra/nodes/node_registration_storage_effect/node.py +112 -0
  515. omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
  516. omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
  517. omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
  518. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +215 -0
  519. omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
  520. omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -0
  521. omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
  522. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
  523. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
  524. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +417 -0
  525. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
  526. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
  527. omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
  528. omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
  529. omnibase_infra/nodes/node_registry_effect/node.py +165 -0
  530. omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
  531. omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
  532. omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
  533. omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
  534. omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
  535. omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
  536. omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
  537. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
  538. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
  539. omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
  540. omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
  541. omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
  542. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
  543. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
  544. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
  545. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
  546. omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
  547. omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
  548. omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
  549. omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
  550. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +222 -0
  551. omnibase_infra/nodes/reducers/__init__.py +30 -0
  552. omnibase_infra/nodes/reducers/models/__init__.py +37 -0
  553. omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
  554. omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -0
  555. omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
  556. omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
  557. omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
  558. omnibase_infra/nodes/reducers/registration_reducer.py +1138 -0
  559. omnibase_infra/observability/__init__.py +143 -0
  560. omnibase_infra/observability/constants_metrics.py +91 -0
  561. omnibase_infra/observability/factory_observability_sink.py +525 -0
  562. omnibase_infra/observability/handlers/__init__.py +118 -0
  563. omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
  564. omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
  565. omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
  566. omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
  567. omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
  568. omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
  569. omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
  570. omnibase_infra/observability/hooks/__init__.py +74 -0
  571. omnibase_infra/observability/hooks/hook_observability.py +1223 -0
  572. omnibase_infra/observability/models/__init__.py +30 -0
  573. omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
  574. omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
  575. omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
  576. omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
  577. omnibase_infra/observability/sinks/__init__.py +69 -0
  578. omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
  579. omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
  580. omnibase_infra/plugins/__init__.py +27 -0
  581. omnibase_infra/plugins/examples/__init__.py +28 -0
  582. omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
  583. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
  584. omnibase_infra/plugins/models/__init__.py +21 -0
  585. omnibase_infra/plugins/models/model_plugin_context.py +76 -0
  586. omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
  587. omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
  588. omnibase_infra/plugins/plugin_compute_base.py +449 -0
  589. omnibase_infra/projectors/__init__.py +30 -0
  590. omnibase_infra/projectors/contracts/__init__.py +63 -0
  591. omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
  592. omnibase_infra/projectors/projection_reader_registration.py +1559 -0
  593. omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
  594. omnibase_infra/protocols/__init__.py +104 -0
  595. omnibase_infra/protocols/protocol_capability_projection.py +253 -0
  596. omnibase_infra/protocols/protocol_capability_query.py +251 -0
  597. omnibase_infra/protocols/protocol_container_aware.py +200 -0
  598. omnibase_infra/protocols/protocol_dispatch_engine.py +152 -0
  599. omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
  600. omnibase_infra/protocols/protocol_event_projector.py +96 -0
  601. omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
  602. omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
  603. omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
  604. omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
  605. omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
  606. omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
  607. omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
  608. omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
  609. omnibase_infra/runtime/__init__.py +445 -0
  610. omnibase_infra/runtime/binding_config_resolver.py +2771 -0
  611. omnibase_infra/runtime/binding_resolver.py +753 -0
  612. omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
  613. omnibase_infra/runtime/constants_notification.py +75 -0
  614. omnibase_infra/runtime/constants_security.py +70 -0
  615. omnibase_infra/runtime/contract_handler_discovery.py +587 -0
  616. omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
  617. omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
  618. omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
  619. omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
  620. omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
  621. omnibase_infra/runtime/emit_daemon/cli.py +844 -0
  622. omnibase_infra/runtime/emit_daemon/client.py +811 -0
  623. omnibase_infra/runtime/emit_daemon/config.py +535 -0
  624. omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
  625. omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
  626. omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
  627. omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
  628. omnibase_infra/runtime/emit_daemon/queue.py +618 -0
  629. omnibase_infra/runtime/enums/__init__.py +18 -0
  630. omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
  631. omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
  632. omnibase_infra/runtime/envelope_validator.py +179 -0
  633. omnibase_infra/runtime/event_bus_subcontract_wiring.py +466 -0
  634. omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
  635. omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
  636. omnibase_infra/runtime/handler_contract_source.py +750 -0
  637. omnibase_infra/runtime/handler_identity.py +81 -0
  638. omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
  639. omnibase_infra/runtime/handler_registry.py +329 -0
  640. omnibase_infra/runtime/handler_source_resolver.py +367 -0
  641. omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
  642. omnibase_infra/runtime/kafka_contract_source.py +984 -0
  643. omnibase_infra/runtime/kernel.py +40 -0
  644. omnibase_infra/runtime/mixin_policy_validation.py +522 -0
  645. omnibase_infra/runtime/mixin_semver_cache.py +402 -0
  646. omnibase_infra/runtime/mixins/__init__.py +24 -0
  647. omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
  648. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
  649. omnibase_infra/runtime/models/__init__.py +229 -0
  650. omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
  651. omnibase_infra/runtime/models/model_binding_config.py +168 -0
  652. omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
  653. omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
  654. omnibase_infra/runtime/models/model_cached_secret.py +138 -0
  655. omnibase_infra/runtime/models/model_compute_key.py +138 -0
  656. omnibase_infra/runtime/models/model_compute_registration.py +97 -0
  657. omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
  658. omnibase_infra/runtime/models/model_config_ref.py +331 -0
  659. omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
  660. omnibase_infra/runtime/models/model_contract_load_result.py +224 -0
  661. omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
  662. omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
  663. omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
  664. omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
  665. omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
  666. omnibase_infra/runtime/models/model_failed_component.py +55 -0
  667. omnibase_infra/runtime/models/model_health_check_response.py +168 -0
  668. omnibase_infra/runtime/models/model_health_check_result.py +229 -0
  669. omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
  670. omnibase_infra/runtime/models/model_logging_config.py +42 -0
  671. omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
  672. omnibase_infra/runtime/models/model_optional_string.py +94 -0
  673. omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
  674. omnibase_infra/runtime/models/model_policy_context.py +100 -0
  675. omnibase_infra/runtime/models/model_policy_key.py +138 -0
  676. omnibase_infra/runtime/models/model_policy_registration.py +139 -0
  677. omnibase_infra/runtime/models/model_policy_result.py +103 -0
  678. omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
  679. omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
  680. omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
  681. omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
  682. omnibase_infra/runtime/models/model_retry_policy.py +105 -0
  683. omnibase_infra/runtime/models/model_runtime_config.py +150 -0
  684. omnibase_infra/runtime/models/model_runtime_contract_config.py +268 -0
  685. omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -0
  686. omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
  687. omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
  688. omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
  689. omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
  690. omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
  691. omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
  692. omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
  693. omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
  694. omnibase_infra/runtime/models/model_security_config.py +109 -0
  695. omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
  696. omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
  697. omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
  698. omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
  699. omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
  700. omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
  701. omnibase_infra/runtime/projector_schema_manager.py +565 -0
  702. omnibase_infra/runtime/projector_shell.py +1330 -0
  703. omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
  704. omnibase_infra/runtime/protocol_contract_source.py +92 -0
  705. omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
  706. omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
  707. omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
  708. omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
  709. omnibase_infra/runtime/protocol_policy.py +366 -0
  710. omnibase_infra/runtime/protocols/__init__.py +37 -0
  711. omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
  712. omnibase_infra/runtime/publisher_topic_scoped.py +294 -0
  713. omnibase_infra/runtime/registry/__init__.py +93 -0
  714. omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
  715. omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
  716. omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
  717. omnibase_infra/runtime/registry/registry_message_type.py +542 -0
  718. omnibase_infra/runtime/registry/registry_protocol_binding.py +445 -0
  719. omnibase_infra/runtime/registry_compute.py +1143 -0
  720. omnibase_infra/runtime/registry_contract_source.py +693 -0
  721. omnibase_infra/runtime/registry_dispatcher.py +678 -0
  722. omnibase_infra/runtime/registry_policy.py +1185 -0
  723. omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
  724. omnibase_infra/runtime/runtime_scheduler.py +1070 -0
  725. omnibase_infra/runtime/secret_resolver.py +2112 -0
  726. omnibase_infra/runtime/security_metadata_validator.py +776 -0
  727. omnibase_infra/runtime/service_kernel.py +1651 -0
  728. omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
  729. omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
  730. omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
  731. omnibase_infra/runtime/transition_notification_publisher.py +765 -0
  732. omnibase_infra/runtime/util_container_wiring.py +1124 -0
  733. omnibase_infra/runtime/util_validation.py +314 -0
  734. omnibase_infra/runtime/util_version.py +98 -0
  735. omnibase_infra/runtime/util_wiring.py +723 -0
  736. omnibase_infra/schemas/schema_registration_projection.sql +320 -0
  737. omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
  738. omnibase_infra/services/__init__.py +89 -0
  739. omnibase_infra/services/corpus_capture.py +684 -0
  740. omnibase_infra/services/mcp/__init__.py +31 -0
  741. omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
  742. omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
  743. omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
  744. omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
  745. omnibase_infra/services/registry_api/__init__.py +40 -0
  746. omnibase_infra/services/registry_api/main.py +261 -0
  747. omnibase_infra/services/registry_api/models/__init__.py +66 -0
  748. omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
  749. omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
  750. omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
  751. omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
  752. omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
  753. omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
  754. omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
  755. omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
  756. omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
  757. omnibase_infra/services/registry_api/models/model_warning.py +49 -0
  758. omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
  759. omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
  760. omnibase_infra/services/registry_api/routes.py +371 -0
  761. omnibase_infra/services/registry_api/service.py +837 -0
  762. omnibase_infra/services/service_capability_query.py +945 -0
  763. omnibase_infra/services/service_health.py +898 -0
  764. omnibase_infra/services/service_node_selector.py +530 -0
  765. omnibase_infra/services/service_timeout_emitter.py +699 -0
  766. omnibase_infra/services/service_timeout_scanner.py +394 -0
  767. omnibase_infra/services/session/__init__.py +56 -0
  768. omnibase_infra/services/session/config_consumer.py +137 -0
  769. omnibase_infra/services/session/config_store.py +139 -0
  770. omnibase_infra/services/session/consumer.py +1007 -0
  771. omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
  772. omnibase_infra/services/session/store.py +997 -0
  773. omnibase_infra/services/snapshot/__init__.py +31 -0
  774. omnibase_infra/services/snapshot/service_snapshot.py +647 -0
  775. omnibase_infra/services/snapshot/store_inmemory.py +637 -0
  776. omnibase_infra/services/snapshot/store_postgres.py +1279 -0
  777. omnibase_infra/shared/__init__.py +8 -0
  778. omnibase_infra/testing/__init__.py +10 -0
  779. omnibase_infra/testing/utils.py +23 -0
  780. omnibase_infra/topics/__init__.py +45 -0
  781. omnibase_infra/topics/platform_topic_suffixes.py +140 -0
  782. omnibase_infra/topics/util_topic_composition.py +95 -0
  783. omnibase_infra/types/__init__.py +48 -0
  784. omnibase_infra/types/type_cache_info.py +49 -0
  785. omnibase_infra/types/type_dsn.py +173 -0
  786. omnibase_infra/types/type_infra_aliases.py +60 -0
  787. omnibase_infra/types/typed_dict/__init__.py +29 -0
  788. omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -0
  789. omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
  790. omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
  791. omnibase_infra/types/typed_dict_capabilities.py +64 -0
  792. omnibase_infra/utils/__init__.py +117 -0
  793. omnibase_infra/utils/correlation.py +208 -0
  794. omnibase_infra/utils/util_atomic_file.py +261 -0
  795. omnibase_infra/utils/util_consumer_group.py +232 -0
  796. omnibase_infra/utils/util_datetime.py +372 -0
  797. omnibase_infra/utils/util_db_transaction.py +239 -0
  798. omnibase_infra/utils/util_dsn_validation.py +333 -0
  799. omnibase_infra/utils/util_env_parsing.py +264 -0
  800. omnibase_infra/utils/util_error_sanitization.py +457 -0
  801. omnibase_infra/utils/util_pydantic_validators.py +477 -0
  802. omnibase_infra/utils/util_retry_optimistic.py +281 -0
  803. omnibase_infra/utils/util_semver.py +233 -0
  804. omnibase_infra/validation/__init__.py +307 -0
  805. omnibase_infra/validation/contracts/security.validation.yaml +114 -0
  806. omnibase_infra/validation/enums/__init__.py +11 -0
  807. omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
  808. omnibase_infra/validation/infra_validators.py +1514 -0
  809. omnibase_infra/validation/linter_contract.py +907 -0
  810. omnibase_infra/validation/mixin_any_type_classification.py +120 -0
  811. omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
  812. omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
  813. omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
  814. omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
  815. omnibase_infra/validation/models/__init__.py +15 -0
  816. omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
  817. omnibase_infra/validation/models/model_contract_violation.py +41 -0
  818. omnibase_infra/validation/service_validation_aggregator.py +395 -0
  819. omnibase_infra/validation/validation_exemptions.yaml +2033 -0
  820. omnibase_infra/validation/validator_any_type.py +715 -0
  821. omnibase_infra/validation/validator_chain_propagation.py +839 -0
  822. omnibase_infra/validation/validator_execution_shape.py +465 -0
  823. omnibase_infra/validation/validator_localhandler.py +261 -0
  824. omnibase_infra/validation/validator_registration_security.py +410 -0
  825. omnibase_infra/validation/validator_routing_coverage.py +1020 -0
  826. omnibase_infra/validation/validator_runtime_shape.py +915 -0
  827. omnibase_infra/validation/validator_security.py +513 -0
  828. omnibase_infra/validation/validator_topic_category.py +1152 -0
  829. omnibase_infra-0.2.6.dist-info/METADATA +197 -0
  830. omnibase_infra-0.2.6.dist-info/RECORD +833 -0
  831. omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
  832. omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
  833. omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1076 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Qdrant Vector Store Handler - implements ProtocolVectorStoreHandler.
4
+
5
+ This handler provides vector store operations for the Qdrant vector database
6
+ using the qdrant-client library with circuit breaker pattern for fault tolerance.
7
+
8
+ Supported Operations:
9
+ - store_embedding: Store a single embedding vector
10
+ - store_embeddings_batch: Batch store multiple embeddings
11
+ - query_similar: Similarity search with metadata filtering
12
+ - delete_embedding: Delete single embedding by ID
13
+ - delete_embeddings_batch: Batch delete embeddings
14
+ - create_index: Create a new collection/index
15
+ - delete_index: Delete a collection/index
16
+ - health_check: Check Qdrant connectivity and status
17
+ - describe: Return handler capabilities and metadata
18
+
19
+ Protocol Implementation:
20
+ This handler implements ProtocolVectorStoreHandler from omnibase_spi.protocols.storage.
21
+ All methods use typed models from omnibase_core.models.vector for type safety.
22
+
23
+ Circuit Breaker Pattern:
24
+ Uses MixinAsyncCircuitBreaker for fault tolerance with configurable
25
+ failure threshold and reset timeout.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import logging
31
+ import time
32
+ from collections.abc import Mapping
33
+ from datetime import UTC, datetime
34
+ from uuid import UUID, uuid4
35
+
36
+ from qdrant_client import QdrantClient
37
+ from qdrant_client.http import models as qdrant_models
38
+
39
+ from omnibase_core.container import ModelONEXContainer
40
+ from omnibase_core.models.common.model_schema_value import ModelSchemaValue
41
+ from omnibase_core.models.vector import (
42
+ EnumVectorDistanceMetric,
43
+ EnumVectorFilterOperator,
44
+ ModelEmbedding,
45
+ ModelVectorBatchStoreResult,
46
+ ModelVectorConnectionConfig,
47
+ ModelVectorDeleteResult,
48
+ ModelVectorHandlerMetadata,
49
+ ModelVectorHealthStatus,
50
+ ModelVectorIndexConfig,
51
+ ModelVectorIndexResult,
52
+ ModelVectorMetadataFilter,
53
+ ModelVectorSearchResult,
54
+ ModelVectorSearchResults,
55
+ ModelVectorStoreResult,
56
+ )
57
+ from omnibase_core.types import JsonType
58
+ from omnibase_infra.enums import EnumInfraTransportType
59
+ from omnibase_infra.errors import (
60
+ InfraAuthenticationError,
61
+ InfraConnectionError,
62
+ InfraUnavailableError,
63
+ ModelInfraErrorContext,
64
+ RuntimeHostError,
65
+ )
66
+ from omnibase_infra.mixins import MixinAsyncCircuitBreaker
67
+ from omnibase_spi.protocols.storage import ProtocolVectorStoreHandler
68
+
69
+ logger = logging.getLogger(__name__)
70
+
71
+ # Default configuration
72
+ _DEFAULT_TIMEOUT_SECONDS: float = 30.0
73
+ _DEFAULT_BATCH_SIZE: int = 100
74
+ _HANDLER_VERSION: str = "1.0.0"
75
+ _HEALTH_CACHE_TTL_SECONDS: float = 5.0
76
+
77
+ # Metric mapping from string to Qdrant distance enum
78
+ _METRIC_MAP: dict[str, qdrant_models.Distance] = {
79
+ "cosine": qdrant_models.Distance.COSINE,
80
+ "euclidean": qdrant_models.Distance.EUCLID,
81
+ "dot_product": qdrant_models.Distance.DOT,
82
+ }
83
+
84
+ # Reverse mapping from EnumVectorDistanceMetric to Qdrant
85
+ _ENUM_TO_QDRANT_METRIC: dict[EnumVectorDistanceMetric, qdrant_models.Distance] = {
86
+ EnumVectorDistanceMetric.COSINE: qdrant_models.Distance.COSINE,
87
+ EnumVectorDistanceMetric.EUCLIDEAN: qdrant_models.Distance.EUCLID,
88
+ EnumVectorDistanceMetric.DOT_PRODUCT: qdrant_models.Distance.DOT,
89
+ }
90
+
91
+ # Filter operator mapping
92
+ _FILTER_OP_MAP: dict[EnumVectorFilterOperator, str] = {
93
+ EnumVectorFilterOperator.EQ: "match",
94
+ EnumVectorFilterOperator.NE: "match_except",
95
+ EnumVectorFilterOperator.GT: "range",
96
+ EnumVectorFilterOperator.GTE: "range",
97
+ EnumVectorFilterOperator.LT: "range",
98
+ EnumVectorFilterOperator.LTE: "range",
99
+ EnumVectorFilterOperator.IN: "match_any",
100
+ EnumVectorFilterOperator.NOT_IN: "match_except_any",
101
+ }
102
+
103
+
104
+ class HandlerQdrant(MixinAsyncCircuitBreaker, ProtocolVectorStoreHandler):
105
+ """Qdrant vector store handler implementing ProtocolVectorStoreHandler.
106
+
107
+ This handler provides vector storage, similarity search, and index management
108
+ operations for the Qdrant vector database.
109
+
110
+ Security Policy:
111
+ API keys are treated as secrets and never logged or exposed in errors.
112
+
113
+ Circuit Breaker Pattern:
114
+ Uses MixinAsyncCircuitBreaker for fault tolerance.
115
+ Configurable failure_threshold and reset_timeout.
116
+
117
+ Thread Safety:
118
+ This handler is NOT thread-safe. Use separate instances for concurrent
119
+ access from different threads. It is coroutine-safe for async operations.
120
+ """
121
+
122
+ def __init__(self, container: ModelONEXContainer) -> None:
123
+ """Initialize HandlerQdrant with ONEX container for dependency injection.
124
+
125
+ Args:
126
+ container: ONEX container providing dependency injection for
127
+ services, configuration, and runtime context.
128
+
129
+ Note:
130
+ The container is stored for interface compliance with the standard ONEX
131
+ handler pattern (def __init__(self, container: ModelONEXContainer)) and
132
+ to enable future DI-based service resolution (e.g., dispatcher routing,
133
+ metrics integration). Currently, the handler operates independently but
134
+ the container parameter ensures API consistency across all handlers.
135
+ """
136
+ self._container = container
137
+ self._client: QdrantClient | None = None
138
+ self._config: ModelVectorConnectionConfig | None = None
139
+ self._default_index: str | None = None
140
+ self._timeout: float = _DEFAULT_TIMEOUT_SECONDS
141
+ self._initialized: bool = False
142
+ # Health check caching
143
+ self._cached_health: ModelVectorHealthStatus | None = None
144
+ self._health_cache_time: float = 0.0
145
+
146
+ @property
147
+ def handler_type(self) -> str:
148
+ """Return the type of handler as a string identifier.
149
+
150
+ Returns:
151
+ String identifier "vector_store" for this handler type.
152
+ """
153
+ return "vector_store"
154
+
155
+ @property
156
+ def supported_metrics(self) -> list[str]:
157
+ """Return the list of distance metrics supported by this handler.
158
+
159
+ Returns:
160
+ List of supported metric names: cosine, euclidean, dot_product.
161
+ """
162
+ return ["cosine", "euclidean", "dot_product"]
163
+
164
+ async def initialize(
165
+ self,
166
+ connection_config: ModelVectorConnectionConfig,
167
+ ) -> None:
168
+ """Initialize the Qdrant client with connection configuration.
169
+
170
+ Establishes connection to the Qdrant server, validates credentials,
171
+ and prepares the handler for operations.
172
+
173
+ Args:
174
+ connection_config: Configuration model containing connection parameters.
175
+
176
+ Raises:
177
+ RuntimeHostError: If configuration is invalid.
178
+ InfraConnectionError: If connection to Qdrant server fails.
179
+ InfraAuthenticationError: If API key authentication fails.
180
+ """
181
+ init_correlation_id = uuid4()
182
+ logger.info(
183
+ "Initializing %s",
184
+ self.__class__.__name__,
185
+ extra={
186
+ "handler": self.__class__.__name__,
187
+ "correlation_id": str(init_correlation_id),
188
+ },
189
+ )
190
+
191
+ self._config = connection_config
192
+ self._timeout = connection_config.timeout
193
+
194
+ # Extract API key safely using SecretStr
195
+ api_key: str | None = None
196
+ if connection_config.api_key is not None:
197
+ api_key = connection_config.api_key.get_secret_value()
198
+
199
+ # Create client
200
+ try:
201
+ self._client = QdrantClient(
202
+ url=connection_config.url,
203
+ api_key=api_key,
204
+ timeout=int(self._timeout),
205
+ )
206
+ # Test connection by listing collections
207
+ self._client.get_collections()
208
+ self._initialized = True
209
+ logger.info(
210
+ "%s initialized successfully",
211
+ self.__class__.__name__,
212
+ extra={
213
+ "handler": self.__class__.__name__,
214
+ "correlation_id": str(init_correlation_id),
215
+ },
216
+ )
217
+ except Exception as e:
218
+ ctx = ModelInfraErrorContext.with_correlation(
219
+ correlation_id=init_correlation_id,
220
+ transport_type=EnumInfraTransportType.QDRANT,
221
+ operation="initialize",
222
+ target_name="qdrant_handler",
223
+ )
224
+ error_msg = str(e).lower()
225
+ if "unauthorized" in error_msg or "forbidden" in error_msg:
226
+ raise InfraAuthenticationError(
227
+ "Qdrant authentication failed - check API key", context=ctx
228
+ ) from e
229
+ raise InfraConnectionError(
230
+ "Failed to connect to Qdrant server", context=ctx
231
+ ) from e
232
+
233
+ # Initialize circuit breaker
234
+ self._init_circuit_breaker(
235
+ threshold=5,
236
+ reset_timeout=60.0,
237
+ service_name="qdrant",
238
+ transport_type=EnumInfraTransportType.QDRANT,
239
+ )
240
+
241
+ async def shutdown(self, timeout_seconds: float = 30.0) -> None:
242
+ """Release resources and close connections to Qdrant.
243
+
244
+ Args:
245
+ timeout_seconds: Maximum time to wait for shutdown to complete.
246
+ """
247
+ if self._client is not None:
248
+ self._client.close()
249
+ self._client = None
250
+ self._initialized = False
251
+ # Clear health cache
252
+ self._cached_health = None
253
+ self._health_cache_time = 0.0
254
+ logger.info("HandlerQdrant shutdown complete")
255
+
256
+ def _ensure_initialized(
257
+ self, operation: str, correlation_id: UUID | None = None
258
+ ) -> None:
259
+ """Ensure the handler is initialized before operations.
260
+
261
+ Args:
262
+ operation: Name of the operation being attempted.
263
+ correlation_id: Optional correlation ID for error context.
264
+
265
+ Raises:
266
+ RuntimeHostError: If handler is not initialized.
267
+ """
268
+ if not self._initialized or self._client is None:
269
+ ctx = ModelInfraErrorContext.with_correlation(
270
+ correlation_id=correlation_id,
271
+ transport_type=EnumInfraTransportType.QDRANT,
272
+ operation=operation,
273
+ target_name="qdrant_handler",
274
+ )
275
+ raise RuntimeHostError(
276
+ "HandlerQdrant not initialized. Call initialize() first.",
277
+ context=ctx,
278
+ )
279
+
280
+ def _resolve_index_name(self, index_name: str | None) -> str:
281
+ """Resolve index name, using default if not provided.
282
+
283
+ Args:
284
+ index_name: Provided index name or None.
285
+
286
+ Returns:
287
+ Resolved index name.
288
+
289
+ Raises:
290
+ RuntimeHostError: If no index name available.
291
+ """
292
+ if index_name:
293
+ return index_name
294
+ if self._default_index:
295
+ return self._default_index
296
+ raise RuntimeHostError("No index_name provided and no default index configured")
297
+
298
+ def _convert_metadata_to_qdrant(
299
+ self, metadata: Mapping[str, JsonType] | None
300
+ ) -> dict[str, object]:
301
+ """Convert metadata mapping to Qdrant payload format.
302
+
303
+ Args:
304
+ metadata: Optional metadata mapping with JsonValue types.
305
+
306
+ Returns:
307
+ Dictionary suitable for Qdrant payload.
308
+ """
309
+ if metadata is None:
310
+ return {}
311
+ return dict(metadata.items())
312
+
313
+ def _convert_model_metadata_to_qdrant(
314
+ self, metadata: dict[str, ModelSchemaValue]
315
+ ) -> dict[str, object]:
316
+ """Convert ModelSchemaValue metadata to Qdrant payload format.
317
+
318
+ Args:
319
+ metadata: Metadata with ModelSchemaValue types.
320
+
321
+ Returns:
322
+ Dictionary suitable for Qdrant payload.
323
+ """
324
+ return {k: v.to_value() for k, v in metadata.items()}
325
+
326
+ def _convert_qdrant_payload_to_metadata(
327
+ self, payload: dict[str, object] | None
328
+ ) -> dict[str, ModelSchemaValue]:
329
+ """Convert Qdrant payload to ModelSchemaValue metadata.
330
+
331
+ Args:
332
+ payload: Qdrant point payload.
333
+
334
+ Returns:
335
+ Metadata dictionary with ModelSchemaValue types.
336
+ """
337
+ if payload is None:
338
+ return {}
339
+ return {k: ModelSchemaValue.from_value(v) for k, v in payload.items()}
340
+
341
+ def _build_qdrant_filter(
342
+ self, filter_metadata: ModelVectorMetadataFilter
343
+ ) -> qdrant_models.Filter:
344
+ """Build Qdrant filter from ModelVectorMetadataFilter.
345
+
346
+ Args:
347
+ filter_metadata: Filter specification.
348
+
349
+ Returns:
350
+ Qdrant Filter object.
351
+ """
352
+ field = filter_metadata.field
353
+ operator = filter_metadata.operator
354
+ value = filter_metadata.value.to_value()
355
+
356
+ conditions: list[qdrant_models.FieldCondition] = []
357
+
358
+ if operator == EnumVectorFilterOperator.EQ:
359
+ conditions.append(
360
+ qdrant_models.FieldCondition(
361
+ key=field,
362
+ match=qdrant_models.MatchValue(value=value),
363
+ )
364
+ )
365
+ elif operator == EnumVectorFilterOperator.NE:
366
+ # Use must_not for not-equal
367
+ return qdrant_models.Filter(
368
+ must_not=[
369
+ qdrant_models.FieldCondition(
370
+ key=field,
371
+ match=qdrant_models.MatchValue(value=value),
372
+ )
373
+ ]
374
+ )
375
+ elif operator in (
376
+ EnumVectorFilterOperator.GT,
377
+ EnumVectorFilterOperator.GTE,
378
+ EnumVectorFilterOperator.LT,
379
+ EnumVectorFilterOperator.LTE,
380
+ ):
381
+ range_params: dict[str, float | int | None] = {
382
+ "gt": None,
383
+ "gte": None,
384
+ "lt": None,
385
+ "lte": None,
386
+ }
387
+ if operator == EnumVectorFilterOperator.GT:
388
+ range_params["gt"] = value # type: ignore[assignment]
389
+ elif operator == EnumVectorFilterOperator.GTE:
390
+ range_params["gte"] = value # type: ignore[assignment]
391
+ elif operator == EnumVectorFilterOperator.LT:
392
+ range_params["lt"] = value # type: ignore[assignment]
393
+ elif operator == EnumVectorFilterOperator.LTE:
394
+ range_params["lte"] = value # type: ignore[assignment]
395
+ conditions.append(
396
+ qdrant_models.FieldCondition(
397
+ key=field,
398
+ range=qdrant_models.Range(**range_params), # type: ignore[arg-type]
399
+ )
400
+ )
401
+ elif operator == EnumVectorFilterOperator.IN:
402
+ if isinstance(value, list):
403
+ conditions.append(
404
+ qdrant_models.FieldCondition(
405
+ key=field,
406
+ match=qdrant_models.MatchAny(any=value),
407
+ )
408
+ )
409
+ elif operator == EnumVectorFilterOperator.NOT_IN:
410
+ if isinstance(value, list):
411
+ return qdrant_models.Filter(
412
+ must_not=[
413
+ qdrant_models.FieldCondition(
414
+ key=field,
415
+ match=qdrant_models.MatchAny(any=value),
416
+ )
417
+ ]
418
+ )
419
+ elif operator == EnumVectorFilterOperator.CONTAINS:
420
+ conditions.append(
421
+ qdrant_models.FieldCondition(
422
+ key=field,
423
+ match=qdrant_models.MatchText(text=str(value)),
424
+ )
425
+ )
426
+ elif operator == EnumVectorFilterOperator.EXISTS:
427
+ conditions.append(
428
+ qdrant_models.FieldCondition(
429
+ key=field,
430
+ is_null=qdrant_models.IsNullCondition(is_null=False),
431
+ )
432
+ )
433
+
434
+ return qdrant_models.Filter(must=conditions)
435
+
436
+ async def store_embedding(
437
+ self,
438
+ embedding_id: str,
439
+ vector: list[float],
440
+ metadata: Mapping[str, JsonType] | None = None,
441
+ index_name: str | None = None,
442
+ ) -> ModelVectorStoreResult:
443
+ """Store a single embedding vector with optional metadata.
444
+
445
+ Args:
446
+ embedding_id: Unique identifier for the embedding.
447
+ vector: The embedding vector as a list of floats.
448
+ metadata: Optional metadata mapping to store with the embedding.
449
+ index_name: Name of the index/collection to store in.
450
+
451
+ Returns:
452
+ ModelVectorStoreResult containing operation result.
453
+
454
+ Raises:
455
+ RuntimeHostError: If handler not initialized.
456
+ InfraConnectionError: If storage operation fails.
457
+ """
458
+ correlation_id = uuid4()
459
+ self._ensure_initialized("store_embedding", correlation_id)
460
+
461
+ resolved_index = self._resolve_index_name(index_name)
462
+
463
+ # Check circuit breaker
464
+ async with self._circuit_breaker_lock:
465
+ await self._check_circuit_breaker("store_embedding", correlation_id)
466
+
467
+ try:
468
+ if self._client is None:
469
+ raise RuntimeHostError("Client is None after initialization check")
470
+
471
+ payload = self._convert_metadata_to_qdrant(metadata)
472
+ self._client.upsert(
473
+ collection_name=resolved_index,
474
+ points=[
475
+ qdrant_models.PointStruct(
476
+ id=embedding_id,
477
+ vector=vector,
478
+ payload=payload,
479
+ )
480
+ ],
481
+ )
482
+
483
+ # Reset circuit breaker on success
484
+ async with self._circuit_breaker_lock:
485
+ await self._reset_circuit_breaker()
486
+
487
+ return ModelVectorStoreResult(
488
+ success=True,
489
+ embedding_id=embedding_id,
490
+ index_name=resolved_index,
491
+ timestamp=datetime.now(UTC),
492
+ )
493
+ except (InfraUnavailableError, RuntimeHostError):
494
+ raise
495
+ except Exception as e:
496
+ ctx = ModelInfraErrorContext.with_correlation(
497
+ correlation_id=correlation_id,
498
+ transport_type=EnumInfraTransportType.QDRANT,
499
+ operation="store_embedding",
500
+ target_name=resolved_index,
501
+ )
502
+ async with self._circuit_breaker_lock:
503
+ await self._record_circuit_failure("store_embedding", correlation_id)
504
+ raise InfraConnectionError(
505
+ f"Failed to store embedding: {type(e).__name__}", context=ctx
506
+ ) from e
507
+
508
+ async def store_embeddings_batch(
509
+ self,
510
+ embeddings: list[ModelEmbedding],
511
+ index_name: str | None = None,
512
+ batch_size: int = 100,
513
+ ) -> ModelVectorBatchStoreResult:
514
+ """Store multiple embeddings efficiently in a batch operation.
515
+
516
+ Args:
517
+ embeddings: List of ModelEmbedding instances.
518
+ index_name: Name of the index/collection to store in.
519
+ batch_size: Number of embeddings to process per batch.
520
+
521
+ Returns:
522
+ ModelVectorBatchStoreResult containing batch operation result.
523
+
524
+ Raises:
525
+ RuntimeHostError: If handler not initialized.
526
+ InfraConnectionError: If batch operation fails.
527
+ """
528
+ correlation_id = uuid4()
529
+ self._ensure_initialized("store_embeddings_batch", correlation_id)
530
+
531
+ resolved_index = self._resolve_index_name(index_name)
532
+ start_time = time.time()
533
+
534
+ # Check circuit breaker
535
+ async with self._circuit_breaker_lock:
536
+ await self._check_circuit_breaker("store_embeddings_batch", correlation_id)
537
+
538
+ total_stored = 0
539
+ failed_ids: list[str] = []
540
+
541
+ try:
542
+ if self._client is None:
543
+ raise RuntimeHostError("Client is None after initialization check")
544
+
545
+ # Process in batches
546
+ for i in range(0, len(embeddings), batch_size):
547
+ batch = embeddings[i : i + batch_size]
548
+ points = [
549
+ qdrant_models.PointStruct(
550
+ id=emb.id,
551
+ vector=emb.vector,
552
+ payload=self._convert_model_metadata_to_qdrant(emb.metadata),
553
+ )
554
+ for emb in batch
555
+ ]
556
+
557
+ try:
558
+ self._client.upsert(
559
+ collection_name=resolved_index,
560
+ points=points,
561
+ )
562
+ total_stored += len(batch)
563
+ except Exception:
564
+ # Track failed IDs in this batch
565
+ failed_ids.extend([emb.id for emb in batch])
566
+
567
+ # Reset circuit breaker on success
568
+ async with self._circuit_breaker_lock:
569
+ await self._reset_circuit_breaker()
570
+
571
+ execution_time_ms = int((time.time() - start_time) * 1000)
572
+
573
+ return ModelVectorBatchStoreResult(
574
+ success=len(failed_ids) == 0,
575
+ total_stored=total_stored,
576
+ failed_ids=failed_ids,
577
+ execution_time_ms=execution_time_ms,
578
+ )
579
+ except (InfraUnavailableError, RuntimeHostError):
580
+ raise
581
+ except Exception as e:
582
+ ctx = ModelInfraErrorContext.with_correlation(
583
+ correlation_id=correlation_id,
584
+ transport_type=EnumInfraTransportType.QDRANT,
585
+ operation="store_embeddings_batch",
586
+ target_name=resolved_index,
587
+ )
588
+ async with self._circuit_breaker_lock:
589
+ await self._record_circuit_failure(
590
+ "store_embeddings_batch", correlation_id
591
+ )
592
+ raise InfraConnectionError(
593
+ f"Batch store failed: {type(e).__name__}", context=ctx
594
+ ) from e
595
+
596
+ async def query_similar(
597
+ self,
598
+ query_vector: list[float],
599
+ top_k: int = 10,
600
+ index_name: str | None = None,
601
+ filter_metadata: ModelVectorMetadataFilter | None = None,
602
+ include_metadata: bool = True,
603
+ include_vectors: bool = False,
604
+ score_threshold: float | None = None,
605
+ ) -> ModelVectorSearchResults:
606
+ """Find similar vectors using similarity/distance search.
607
+
608
+ Args:
609
+ query_vector: The query embedding vector to search against.
610
+ top_k: Maximum number of results to return.
611
+ index_name: Name of the index/collection to search.
612
+ filter_metadata: Optional metadata filter to restrict search.
613
+ include_metadata: Whether to include metadata in results.
614
+ include_vectors: Whether to include vectors in results.
615
+ score_threshold: Minimum similarity score threshold.
616
+
617
+ Returns:
618
+ ModelVectorSearchResults containing search results.
619
+
620
+ Raises:
621
+ RuntimeHostError: If handler not initialized.
622
+ InfraConnectionError: If search operation fails.
623
+ """
624
+ correlation_id = uuid4()
625
+ self._ensure_initialized("query_similar", correlation_id)
626
+
627
+ resolved_index = self._resolve_index_name(index_name)
628
+ start_time = time.time()
629
+
630
+ # Check circuit breaker
631
+ async with self._circuit_breaker_lock:
632
+ await self._check_circuit_breaker("query_similar", correlation_id)
633
+
634
+ try:
635
+ if self._client is None:
636
+ raise RuntimeHostError("Client is None after initialization check")
637
+
638
+ # Build filter if provided
639
+ qdrant_filter: qdrant_models.Filter | None = None
640
+ if filter_metadata is not None:
641
+ qdrant_filter = self._build_qdrant_filter(filter_metadata)
642
+
643
+ # Execute search using query_points API
644
+ query_result = self._client.query_points(
645
+ collection_name=resolved_index,
646
+ query=query_vector,
647
+ limit=top_k,
648
+ query_filter=qdrant_filter,
649
+ with_payload=include_metadata,
650
+ with_vectors=include_vectors,
651
+ score_threshold=score_threshold,
652
+ )
653
+
654
+ # Convert results
655
+ results: list[ModelVectorSearchResult] = []
656
+ for point in query_result.points:
657
+ metadata = (
658
+ self._convert_qdrant_payload_to_metadata(point.payload)
659
+ if point.payload and include_metadata
660
+ else {}
661
+ )
662
+ vector_data: list[float] | None = None
663
+ if include_vectors and point.vector is not None:
664
+ # Handle both list and dict vector formats
665
+ raw_vector = point.vector
666
+ if isinstance(raw_vector, list):
667
+ vector_data = [float(v) for v in raw_vector] # type: ignore[arg-type]
668
+ elif isinstance(raw_vector, dict):
669
+ # For named vectors, get the default one
670
+ first_vector = next(iter(raw_vector.values()), None)
671
+ if first_vector is not None and isinstance(first_vector, list):
672
+ vector_data = [float(v) for v in first_vector] # type: ignore[arg-type]
673
+
674
+ results.append(
675
+ ModelVectorSearchResult(
676
+ id=str(point.id),
677
+ score=float(point.score) if point.score is not None else 0.0,
678
+ metadata=metadata,
679
+ vector=vector_data,
680
+ )
681
+ )
682
+
683
+ # Reset circuit breaker on success
684
+ async with self._circuit_breaker_lock:
685
+ await self._reset_circuit_breaker()
686
+
687
+ query_time_ms = int((time.time() - start_time) * 1000)
688
+
689
+ return ModelVectorSearchResults(
690
+ results=results,
691
+ total_results=len(results),
692
+ query_time_ms=query_time_ms,
693
+ )
694
+ except (InfraUnavailableError, RuntimeHostError):
695
+ raise
696
+ except Exception as e:
697
+ ctx = ModelInfraErrorContext.with_correlation(
698
+ correlation_id=correlation_id,
699
+ transport_type=EnumInfraTransportType.QDRANT,
700
+ operation="query_similar",
701
+ target_name=resolved_index,
702
+ )
703
+ async with self._circuit_breaker_lock:
704
+ await self._record_circuit_failure("query_similar", correlation_id)
705
+ raise InfraConnectionError(
706
+ f"Search failed: {type(e).__name__}", context=ctx
707
+ ) from e
708
+
709
+ async def delete_embedding(
710
+ self,
711
+ embedding_id: str,
712
+ index_name: str | None = None,
713
+ ) -> ModelVectorDeleteResult:
714
+ """Remove a single embedding by ID.
715
+
716
+ Args:
717
+ embedding_id: Unique identifier of the embedding to delete.
718
+ index_name: Name of the index/collection containing the embedding.
719
+
720
+ Returns:
721
+ ModelVectorDeleteResult containing deletion result.
722
+
723
+ Raises:
724
+ RuntimeHostError: If handler not initialized.
725
+ InfraConnectionError: If deletion operation fails.
726
+ """
727
+ correlation_id = uuid4()
728
+ self._ensure_initialized("delete_embedding", correlation_id)
729
+
730
+ resolved_index = self._resolve_index_name(index_name)
731
+
732
+ # Check circuit breaker
733
+ async with self._circuit_breaker_lock:
734
+ await self._check_circuit_breaker("delete_embedding", correlation_id)
735
+
736
+ try:
737
+ if self._client is None:
738
+ raise RuntimeHostError("Client is None after initialization check")
739
+
740
+ self._client.delete(
741
+ collection_name=resolved_index,
742
+ points_selector=qdrant_models.PointIdsList(points=[embedding_id]),
743
+ )
744
+
745
+ # Reset circuit breaker on success
746
+ async with self._circuit_breaker_lock:
747
+ await self._reset_circuit_breaker()
748
+
749
+ return ModelVectorDeleteResult(
750
+ success=True,
751
+ embedding_id=embedding_id,
752
+ deleted=True,
753
+ )
754
+ except (InfraUnavailableError, RuntimeHostError):
755
+ raise
756
+ except Exception as e:
757
+ ctx = ModelInfraErrorContext.with_correlation(
758
+ correlation_id=correlation_id,
759
+ transport_type=EnumInfraTransportType.QDRANT,
760
+ operation="delete_embedding",
761
+ target_name=resolved_index,
762
+ )
763
+ async with self._circuit_breaker_lock:
764
+ await self._record_circuit_failure("delete_embedding", correlation_id)
765
+ raise InfraConnectionError(
766
+ f"Delete failed: {type(e).__name__}", context=ctx
767
+ ) from e
768
+
769
+ async def delete_embeddings_batch(
770
+ self,
771
+ embedding_ids: list[str],
772
+ index_name: str | None = None,
773
+ ) -> ModelVectorDeleteResult:
774
+ """Remove multiple embeddings by their IDs.
775
+
776
+ Args:
777
+ embedding_ids: List of embedding IDs to delete.
778
+ index_name: Name of the index/collection containing the embeddings.
779
+
780
+ Returns:
781
+ ModelVectorDeleteResult containing batch deletion result.
782
+
783
+ Raises:
784
+ RuntimeHostError: If handler not initialized.
785
+ InfraConnectionError: If batch deletion fails.
786
+ """
787
+ correlation_id = uuid4()
788
+ self._ensure_initialized("delete_embeddings_batch", correlation_id)
789
+
790
+ resolved_index = self._resolve_index_name(index_name)
791
+
792
+ # Check circuit breaker
793
+ async with self._circuit_breaker_lock:
794
+ await self._check_circuit_breaker("delete_embeddings_batch", correlation_id)
795
+
796
+ try:
797
+ if self._client is None:
798
+ raise RuntimeHostError("Client is None after initialization check")
799
+
800
+ self._client.delete(
801
+ collection_name=resolved_index,
802
+ points_selector=qdrant_models.PointIdsList(points=embedding_ids),
803
+ )
804
+
805
+ # Reset circuit breaker on success
806
+ async with self._circuit_breaker_lock:
807
+ await self._reset_circuit_breaker()
808
+
809
+ # Return first ID for the single embedding_id field
810
+ # The protocol uses embedding_id singular even for batch
811
+ return ModelVectorDeleteResult(
812
+ success=True,
813
+ embedding_id=embedding_ids[0] if embedding_ids else "",
814
+ deleted=True,
815
+ )
816
+ except (InfraUnavailableError, RuntimeHostError):
817
+ raise
818
+ except Exception as e:
819
+ ctx = ModelInfraErrorContext.with_correlation(
820
+ correlation_id=correlation_id,
821
+ transport_type=EnumInfraTransportType.QDRANT,
822
+ operation="delete_embeddings_batch",
823
+ target_name=resolved_index,
824
+ )
825
+ async with self._circuit_breaker_lock:
826
+ await self._record_circuit_failure(
827
+ "delete_embeddings_batch", correlation_id
828
+ )
829
+ raise InfraConnectionError(
830
+ f"Batch delete failed: {type(e).__name__}", context=ctx
831
+ ) from e
832
+
833
+ async def create_index(
834
+ self,
835
+ index_name: str,
836
+ dimension: int,
837
+ metric: str = "cosine",
838
+ index_config: ModelVectorIndexConfig | None = None,
839
+ ) -> ModelVectorIndexResult:
840
+ """Create a new vector index/collection.
841
+
842
+ Args:
843
+ index_name: Unique name for the new index.
844
+ dimension: Vector dimension.
845
+ metric: Distance metric to use (cosine, euclidean, dot_product).
846
+ index_config: Optional configuration with HNSW and quantization settings.
847
+
848
+ Returns:
849
+ ModelVectorIndexResult containing creation result.
850
+
851
+ Raises:
852
+ RuntimeHostError: If handler not initialized.
853
+ InfraConnectionError: If index creation fails.
854
+ ValueError: If metric is not supported.
855
+ """
856
+ correlation_id = uuid4()
857
+ self._ensure_initialized("create_index", correlation_id)
858
+
859
+ # Validate metric
860
+ metric_lower = metric.lower()
861
+ if metric_lower not in self.supported_metrics:
862
+ raise ValueError(
863
+ f"Unsupported metric '{metric}'. "
864
+ f"Supported: {', '.join(self.supported_metrics)}"
865
+ )
866
+
867
+ # Check circuit breaker
868
+ async with self._circuit_breaker_lock:
869
+ await self._check_circuit_breaker("create_index", correlation_id)
870
+
871
+ try:
872
+ if self._client is None:
873
+ raise RuntimeHostError("Client is None after initialization check")
874
+
875
+ # Map metric string to Qdrant distance enum
876
+ distance_enum = _METRIC_MAP[metric_lower]
877
+
878
+ # Build vectors config
879
+ vectors_config = qdrant_models.VectorParams(
880
+ size=dimension,
881
+ distance=distance_enum,
882
+ )
883
+
884
+ # Apply HNSW config if provided
885
+ hnsw_config: qdrant_models.HnswConfigDiff | None = None
886
+ if index_config and index_config.hnsw_config:
887
+ hnsw_config = qdrant_models.HnswConfigDiff(
888
+ m=index_config.hnsw_config.m,
889
+ ef_construct=index_config.hnsw_config.ef_construction,
890
+ )
891
+
892
+ # Create collection
893
+ self._client.create_collection(
894
+ collection_name=index_name,
895
+ vectors_config=vectors_config,
896
+ hnsw_config=hnsw_config,
897
+ )
898
+
899
+ # Reset circuit breaker on success
900
+ async with self._circuit_breaker_lock:
901
+ await self._reset_circuit_breaker()
902
+
903
+ # Map metric string to enum
904
+ metric_enum = {
905
+ "cosine": EnumVectorDistanceMetric.COSINE,
906
+ "euclidean": EnumVectorDistanceMetric.EUCLIDEAN,
907
+ "dot_product": EnumVectorDistanceMetric.DOT_PRODUCT,
908
+ }.get(metric_lower, EnumVectorDistanceMetric.COSINE)
909
+
910
+ return ModelVectorIndexResult(
911
+ success=True,
912
+ index_name=index_name,
913
+ dimension=dimension,
914
+ metric=metric_enum,
915
+ created_at=datetime.now(UTC),
916
+ )
917
+ except (InfraUnavailableError, RuntimeHostError, ValueError):
918
+ raise
919
+ except Exception as e:
920
+ ctx = ModelInfraErrorContext.with_correlation(
921
+ correlation_id=correlation_id,
922
+ transport_type=EnumInfraTransportType.QDRANT,
923
+ operation="create_index",
924
+ target_name=index_name,
925
+ )
926
+ async with self._circuit_breaker_lock:
927
+ await self._record_circuit_failure("create_index", correlation_id)
928
+ raise InfraConnectionError(
929
+ f"Failed to create index: {type(e).__name__}", context=ctx
930
+ ) from e
931
+
932
+ async def delete_index(
933
+ self,
934
+ index_name: str,
935
+ ) -> ModelVectorIndexResult:
936
+ """Delete a vector index/collection.
937
+
938
+ Args:
939
+ index_name: Name of the index to delete.
940
+
941
+ Returns:
942
+ ModelVectorIndexResult containing deletion result.
943
+
944
+ Raises:
945
+ RuntimeHostError: If handler not initialized.
946
+ InfraConnectionError: If deletion fails.
947
+ """
948
+ correlation_id = uuid4()
949
+ self._ensure_initialized("delete_index", correlation_id)
950
+
951
+ # Check circuit breaker
952
+ async with self._circuit_breaker_lock:
953
+ await self._check_circuit_breaker("delete_index", correlation_id)
954
+
955
+ try:
956
+ if self._client is None:
957
+ raise RuntimeHostError("Client is None after initialization check")
958
+
959
+ self._client.delete_collection(collection_name=index_name)
960
+
961
+ # Reset circuit breaker on success
962
+ async with self._circuit_breaker_lock:
963
+ await self._reset_circuit_breaker()
964
+
965
+ return ModelVectorIndexResult(
966
+ success=True,
967
+ index_name=index_name,
968
+ dimension=0, # Unknown after deletion
969
+ metric=EnumVectorDistanceMetric.COSINE, # Default
970
+ created_at=None,
971
+ )
972
+ except (InfraUnavailableError, RuntimeHostError):
973
+ raise
974
+ except Exception as e:
975
+ ctx = ModelInfraErrorContext.with_correlation(
976
+ correlation_id=correlation_id,
977
+ transport_type=EnumInfraTransportType.QDRANT,
978
+ operation="delete_index",
979
+ target_name=index_name,
980
+ )
981
+ async with self._circuit_breaker_lock:
982
+ await self._record_circuit_failure("delete_index", correlation_id)
983
+ raise InfraConnectionError(
984
+ f"Failed to delete index: {type(e).__name__}", context=ctx
985
+ ) from e
986
+
987
+ async def health_check(self) -> ModelVectorHealthStatus:
988
+ """Check handler health and connectivity to Qdrant.
989
+
990
+ Implements caching to avoid overwhelming the backend with frequent
991
+ health checks. Cache TTL is configured via _HEALTH_CACHE_TTL_SECONDS.
992
+
993
+ Returns:
994
+ ModelVectorHealthStatus containing health status.
995
+ """
996
+ # Return cached result if recent
997
+ current_time = time.time()
998
+ if (
999
+ self._cached_health is not None
1000
+ and current_time - self._health_cache_time < _HEALTH_CACHE_TTL_SECONDS
1001
+ ):
1002
+ return self._cached_health
1003
+
1004
+ start_time = time.time()
1005
+
1006
+ if not self._initialized or self._client is None:
1007
+ return ModelVectorHealthStatus(
1008
+ healthy=False,
1009
+ latency_ms=0,
1010
+ details={},
1011
+ indices=[],
1012
+ last_error="Handler not initialized",
1013
+ )
1014
+
1015
+ try:
1016
+ # List collections to verify connectivity
1017
+ collections_response = self._client.get_collections()
1018
+ collection_names = [c.name for c in collections_response.collections]
1019
+
1020
+ latency_ms = int((time.time() - start_time) * 1000)
1021
+
1022
+ health = ModelVectorHealthStatus(
1023
+ healthy=True,
1024
+ latency_ms=latency_ms,
1025
+ details={
1026
+ "version": ModelSchemaValue.from_value(_HANDLER_VERSION),
1027
+ "backend": ModelSchemaValue.from_value("qdrant"),
1028
+ },
1029
+ indices=collection_names,
1030
+ last_error=None,
1031
+ )
1032
+
1033
+ # Cache the result
1034
+ self._cached_health = health
1035
+ self._health_cache_time = current_time
1036
+
1037
+ return health
1038
+ except Exception as e:
1039
+ latency_ms = int((time.time() - start_time) * 1000)
1040
+ return ModelVectorHealthStatus(
1041
+ healthy=False,
1042
+ latency_ms=latency_ms,
1043
+ details={},
1044
+ indices=[],
1045
+ last_error=f"Health check failed: {type(e).__name__}",
1046
+ )
1047
+
1048
+ async def describe(self) -> ModelVectorHandlerMetadata: # type: ignore[override]
1049
+ """Return handler metadata and capabilities.
1050
+
1051
+ Returns:
1052
+ ModelVectorHandlerMetadata containing handler metadata.
1053
+ """
1054
+ return ModelVectorHandlerMetadata(
1055
+ handler_type="qdrant",
1056
+ capabilities=[
1057
+ "store_embedding",
1058
+ "store_embeddings_batch",
1059
+ "query_similar",
1060
+ "delete_embedding",
1061
+ "delete_embeddings_batch",
1062
+ "create_index",
1063
+ "delete_index",
1064
+ "health_check",
1065
+ "filter_metadata",
1066
+ "score_threshold",
1067
+ ],
1068
+ supported_metrics=[
1069
+ EnumVectorDistanceMetric.COSINE,
1070
+ EnumVectorDistanceMetric.EUCLIDEAN,
1071
+ EnumVectorDistanceMetric.DOT_PRODUCT,
1072
+ ],
1073
+ )
1074
+
1075
+
1076
+ __all__: list[str] = ["HandlerQdrant"]