omnibase_infra 0.2.8__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omnibase_infra/__init__.py +1 -1
- omnibase_infra/enums/__init__.py +4 -0
- omnibase_infra/enums/enum_declarative_node_violation.py +102 -0
- omnibase_infra/errors/__init__.py +18 -0
- omnibase_infra/errors/repository/__init__.py +78 -0
- omnibase_infra/errors/repository/errors_repository.py +424 -0
- omnibase_infra/event_bus/adapters/__init__.py +31 -0
- omnibase_infra/event_bus/adapters/adapter_protocol_event_publisher_kafka.py +517 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +113 -1
- omnibase_infra/models/__init__.py +9 -0
- omnibase_infra/models/event_bus/__init__.py +22 -0
- omnibase_infra/models/event_bus/model_consumer_retry_config.py +367 -0
- omnibase_infra/models/event_bus/model_dlq_config.py +177 -0
- omnibase_infra/models/event_bus/model_idempotency_config.py +131 -0
- omnibase_infra/models/event_bus/model_offset_policy_config.py +107 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +15 -0
- omnibase_infra/models/validation/__init__.py +8 -0
- omnibase_infra/models/validation/model_declarative_node_validation_result.py +139 -0
- omnibase_infra/models/validation/model_declarative_node_violation.py +169 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +28 -7
- omnibase_infra/nodes/architecture_validator/constants.py +36 -0
- omnibase_infra/nodes/architecture_validator/handlers/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/handlers/contract.yaml +120 -0
- omnibase_infra/nodes/architecture_validator/handlers/handler_architecture_validation.py +359 -0
- omnibase_infra/nodes/architecture_validator/node.py +1 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +48 -336
- omnibase_infra/nodes/contract_registry_reducer/reducer.py +12 -2
- omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +16 -2
- omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +14 -4
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/__init__.py +18 -0
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/contract.yaml +53 -0
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/handler_ledger_projection.py +354 -0
- omnibase_infra/nodes/node_ledger_projection_compute/node.py +20 -256
- omnibase_infra/nodes/node_registry_effect/node.py +20 -73
- omnibase_infra/protocols/protocol_dispatch_engine.py +90 -0
- omnibase_infra/runtime/__init__.py +11 -0
- omnibase_infra/runtime/baseline_subscriptions.py +150 -0
- omnibase_infra/runtime/db/__init__.py +73 -0
- omnibase_infra/runtime/db/models/__init__.py +41 -0
- omnibase_infra/runtime/db/models/model_repository_runtime_config.py +211 -0
- omnibase_infra/runtime/db/postgres_repository_runtime.py +545 -0
- omnibase_infra/runtime/event_bus_subcontract_wiring.py +455 -24
- omnibase_infra/runtime/kafka_contract_source.py +13 -5
- omnibase_infra/runtime/service_message_dispatch_engine.py +112 -0
- omnibase_infra/runtime/service_runtime_host_process.py +6 -11
- omnibase_infra/services/__init__.py +36 -0
- omnibase_infra/services/contract_publisher/__init__.py +95 -0
- omnibase_infra/services/contract_publisher/config.py +199 -0
- omnibase_infra/services/contract_publisher/errors.py +243 -0
- omnibase_infra/services/contract_publisher/models/__init__.py +28 -0
- omnibase_infra/services/contract_publisher/models/model_contract_error.py +67 -0
- omnibase_infra/services/contract_publisher/models/model_infra_error.py +62 -0
- omnibase_infra/services/contract_publisher/models/model_publish_result.py +112 -0
- omnibase_infra/services/contract_publisher/models/model_publish_stats.py +79 -0
- omnibase_infra/services/contract_publisher/service.py +617 -0
- omnibase_infra/services/contract_publisher/sources/__init__.py +52 -0
- omnibase_infra/services/contract_publisher/sources/model_discovered.py +155 -0
- omnibase_infra/services/contract_publisher/sources/protocol.py +101 -0
- omnibase_infra/services/contract_publisher/sources/source_composite.py +309 -0
- omnibase_infra/services/contract_publisher/sources/source_filesystem.py +174 -0
- omnibase_infra/services/contract_publisher/sources/source_package.py +221 -0
- omnibase_infra/services/observability/__init__.py +40 -0
- omnibase_infra/services/observability/agent_actions/__init__.py +64 -0
- omnibase_infra/services/observability/agent_actions/config.py +209 -0
- omnibase_infra/services/observability/agent_actions/consumer.py +1320 -0
- omnibase_infra/services/observability/agent_actions/models/__init__.py +87 -0
- omnibase_infra/services/observability/agent_actions/models/model_agent_action.py +142 -0
- omnibase_infra/services/observability/agent_actions/models/model_detection_failure.py +125 -0
- omnibase_infra/services/observability/agent_actions/models/model_envelope.py +85 -0
- omnibase_infra/services/observability/agent_actions/models/model_execution_log.py +159 -0
- omnibase_infra/services/observability/agent_actions/models/model_performance_metric.py +130 -0
- omnibase_infra/services/observability/agent_actions/models/model_routing_decision.py +138 -0
- omnibase_infra/services/observability/agent_actions/models/model_transformation_event.py +124 -0
- omnibase_infra/services/observability/agent_actions/tests/__init__.py +20 -0
- omnibase_infra/services/observability/agent_actions/tests/test_consumer.py +1154 -0
- omnibase_infra/services/observability/agent_actions/tests/test_models.py +645 -0
- omnibase_infra/services/observability/agent_actions/tests/test_writer.py +709 -0
- omnibase_infra/services/observability/agent_actions/writer_postgres.py +926 -0
- omnibase_infra/validation/__init__.py +12 -0
- omnibase_infra/validation/contracts/declarative_node.validation.yaml +143 -0
- omnibase_infra/validation/infra_validators.py +4 -1
- omnibase_infra/validation/validation_exemptions.yaml +111 -0
- omnibase_infra/validation/validator_declarative_node.py +850 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/METADATA +2 -2
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/RECORD +88 -30
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/WHEEL +0 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/entry_points.txt +0 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""Configuration for agent actions observability consumer.
|
|
2
|
+
|
|
3
|
+
Loads from environment variables with OMNIBASE_INFRA_AGENT_ACTIONS_ prefix.
|
|
4
|
+
|
|
5
|
+
Moved from omniclaude as part of OMN-1743 layer-correction cleanup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Self
|
|
12
|
+
|
|
13
|
+
from pydantic import Field, model_validator
|
|
14
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ConfigAgentActionsConsumer(BaseSettings):
|
|
20
|
+
"""Configuration for the agent actions observability Kafka consumer.
|
|
21
|
+
|
|
22
|
+
Environment variables use the OMNIBASE_INFRA_AGENT_ACTIONS_ prefix.
|
|
23
|
+
Example: OMNIBASE_INFRA_AGENT_ACTIONS_KAFKA_BOOTSTRAP_SERVERS=kafka.example.com:9092
|
|
24
|
+
|
|
25
|
+
This consumer subscribes to multiple agent observability topics and
|
|
26
|
+
persists events to PostgreSQL for analytics and debugging.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
model_config = SettingsConfigDict(
|
|
30
|
+
env_prefix="OMNIBASE_INFRA_AGENT_ACTIONS_",
|
|
31
|
+
env_file=".env",
|
|
32
|
+
env_file_encoding="utf-8",
|
|
33
|
+
case_sensitive=False,
|
|
34
|
+
extra="ignore",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Kafka connection
|
|
38
|
+
kafka_bootstrap_servers: str = Field(
|
|
39
|
+
default="localhost:9092",
|
|
40
|
+
description=(
|
|
41
|
+
"Kafka bootstrap servers. Set via "
|
|
42
|
+
"OMNIBASE_INFRA_AGENT_ACTIONS_KAFKA_BOOTSTRAP_SERVERS env var for production."
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
kafka_group_id: str = Field(
|
|
46
|
+
default="agent-observability-postgres",
|
|
47
|
+
description="Consumer group ID for offset tracking",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Topics to subscribe (6 observability topics)
|
|
51
|
+
topics: list[str] = Field(
|
|
52
|
+
default_factory=lambda: [
|
|
53
|
+
"agent-actions",
|
|
54
|
+
"agent-routing-decisions",
|
|
55
|
+
"agent-transformation-events",
|
|
56
|
+
"router-performance-metrics",
|
|
57
|
+
"agent-detection-failures",
|
|
58
|
+
"agent-execution-logs",
|
|
59
|
+
],
|
|
60
|
+
description="Kafka topics to consume for agent observability",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Consumer behavior
|
|
64
|
+
auto_offset_reset: str = Field(
|
|
65
|
+
default="earliest",
|
|
66
|
+
description="Where to start consuming if no offset exists",
|
|
67
|
+
)
|
|
68
|
+
enable_auto_commit: bool = Field(
|
|
69
|
+
default=False,
|
|
70
|
+
description="Disable auto-commit for at-least-once delivery",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# PostgreSQL connection
|
|
74
|
+
postgres_dsn: str = Field(
|
|
75
|
+
description=(
|
|
76
|
+
"PostgreSQL connection string. Set via "
|
|
77
|
+
"OMNIBASE_INFRA_AGENT_ACTIONS_POSTGRES_DSN env var."
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Batch processing
|
|
82
|
+
batch_size: int = Field(
|
|
83
|
+
default=100,
|
|
84
|
+
ge=1,
|
|
85
|
+
le=1000,
|
|
86
|
+
description="Maximum records per batch write",
|
|
87
|
+
)
|
|
88
|
+
batch_timeout_ms: int = Field(
|
|
89
|
+
default=1000,
|
|
90
|
+
ge=100,
|
|
91
|
+
le=60000,
|
|
92
|
+
description="Timeout for batch accumulation in milliseconds",
|
|
93
|
+
)
|
|
94
|
+
poll_timeout_buffer_seconds: float = Field(
|
|
95
|
+
default=5.0,
|
|
96
|
+
ge=1.0,
|
|
97
|
+
le=30.0,
|
|
98
|
+
description=(
|
|
99
|
+
"Additional buffer time in seconds added to batch_timeout_ms for "
|
|
100
|
+
"the asyncio.wait_for timeout when polling Kafka. This buffer accounts "
|
|
101
|
+
"for Kafka client internal processing overhead beyond the poll timeout. "
|
|
102
|
+
"Configure via OMNIBASE_INFRA_AGENT_ACTIONS_POLL_TIMEOUT_BUFFER_SECONDS env var."
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Circuit breaker
|
|
107
|
+
circuit_breaker_threshold: int = Field(
|
|
108
|
+
default=5,
|
|
109
|
+
ge=1,
|
|
110
|
+
le=100,
|
|
111
|
+
description="Failures before circuit opens",
|
|
112
|
+
)
|
|
113
|
+
circuit_breaker_reset_timeout: float = Field(
|
|
114
|
+
default=60.0,
|
|
115
|
+
ge=1.0,
|
|
116
|
+
le=3600.0,
|
|
117
|
+
description="Seconds before circuit half-opens for retry",
|
|
118
|
+
)
|
|
119
|
+
circuit_breaker_half_open_successes: int = Field(
|
|
120
|
+
default=1,
|
|
121
|
+
ge=1,
|
|
122
|
+
le=10,
|
|
123
|
+
description="Successful requests required to close circuit from half-open state",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Health check
|
|
127
|
+
health_check_port: int = Field(
|
|
128
|
+
default=8087,
|
|
129
|
+
ge=1024,
|
|
130
|
+
le=65535,
|
|
131
|
+
description="Port for HTTP health check endpoint",
|
|
132
|
+
)
|
|
133
|
+
health_check_host: str = Field(
|
|
134
|
+
default="0.0.0.0", # noqa: S104 - Configurable, see security note below
|
|
135
|
+
description=(
|
|
136
|
+
"Host/IP for health check server binding. Default '0.0.0.0' binds to all "
|
|
137
|
+
"interfaces for container/Kubernetes probe access. For security-sensitive "
|
|
138
|
+
"deployments, set to '127.0.0.1' to restrict to localhost-only access. "
|
|
139
|
+
"Configure via OMNIBASE_INFRA_AGENT_ACTIONS_HEALTH_CHECK_HOST env var."
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
health_check_staleness_seconds: int = Field(
|
|
143
|
+
default=300,
|
|
144
|
+
ge=60,
|
|
145
|
+
le=3600,
|
|
146
|
+
description=(
|
|
147
|
+
"Maximum age in seconds for the last successful write before "
|
|
148
|
+
"the health check reports DEGRADED status. Lower values detect "
|
|
149
|
+
"stalled consumers faster but may cause false positives in "
|
|
150
|
+
"low-traffic environments. Default is 300 (5 minutes). "
|
|
151
|
+
"Configure via OMNIBASE_INFRA_AGENT_ACTIONS_HEALTH_CHECK_STALENESS_SECONDS env var."
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
health_check_poll_staleness_seconds: int = Field(
|
|
155
|
+
default=60,
|
|
156
|
+
ge=10,
|
|
157
|
+
le=300,
|
|
158
|
+
description=(
|
|
159
|
+
"Maximum age in seconds for the last poll before the health check "
|
|
160
|
+
"reports DEGRADED status. This detects consumers that have stopped "
|
|
161
|
+
"polling Kafka even if they appear to be running. Default is 60 seconds. "
|
|
162
|
+
"Configure via OMNIBASE_INFRA_AGENT_ACTIONS_HEALTH_CHECK_POLL_STALENESS_SECONDS env var."
|
|
163
|
+
),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
@model_validator(mode="after")
|
|
167
|
+
def validate_topic_configuration(self) -> Self:
|
|
168
|
+
"""Ensure topics are configured.
|
|
169
|
+
|
|
170
|
+
Fails fast if no topics provided, preventing silent misconfiguration.
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
Self if validation passes.
|
|
174
|
+
|
|
175
|
+
Raises:
|
|
176
|
+
ProtocolConfigurationError: If no topics are configured.
|
|
177
|
+
"""
|
|
178
|
+
if not self.topics:
|
|
179
|
+
from omnibase_infra.errors import ProtocolConfigurationError
|
|
180
|
+
|
|
181
|
+
raise ProtocolConfigurationError(
|
|
182
|
+
"No topics configured for agent actions consumer. "
|
|
183
|
+
"Provide explicit 'topics' via configuration or environment variable."
|
|
184
|
+
)
|
|
185
|
+
return self
|
|
186
|
+
|
|
187
|
+
@model_validator(mode="after")
|
|
188
|
+
def validate_timing_relationships(self) -> Self:
|
|
189
|
+
"""Validate timing relationships between configuration values.
|
|
190
|
+
|
|
191
|
+
Warns if circuit breaker timeout is very short relative to batch processing,
|
|
192
|
+
which could cause premature circuit opens during normal batch operations.
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Self if validation passes.
|
|
196
|
+
"""
|
|
197
|
+
batch_timeout_seconds = self.batch_timeout_ms / 1000
|
|
198
|
+
min_recommended_circuit_timeout = batch_timeout_seconds * 2
|
|
199
|
+
|
|
200
|
+
if self.circuit_breaker_reset_timeout < min_recommended_circuit_timeout:
|
|
201
|
+
logger.warning(
|
|
202
|
+
"Circuit breaker timeout (%.1fs) is less than 2x batch timeout (%.1fs). "
|
|
203
|
+
"This may cause premature circuit opens during normal batch processing. "
|
|
204
|
+
"Recommended minimum: %.1fs",
|
|
205
|
+
self.circuit_breaker_reset_timeout,
|
|
206
|
+
batch_timeout_seconds,
|
|
207
|
+
min_recommended_circuit_timeout,
|
|
208
|
+
)
|
|
209
|
+
return self
|