diff --git a/pyproject.toml b/pyproject.toml index 1f15a1b0fb..b0d186ea44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "hatchling.build" [project] name = "omnibase_core" -version = "0.43.0" +version = "0.44.0" description = "ONEX Core Framework - Base classes and essential implementations" authors = [ {name = "OmniNode.ai", email = "contact@omninode.ai"} diff --git a/src/omnibase_core/models/delegation/wire/model_bifrost_delegation_config.py b/src/omnibase_core/models/delegation/wire/model_bifrost_delegation_config.py index 3637bf11b1..1990e79319 100644 --- a/src/omnibase_core/models/delegation/wire/model_bifrost_delegation_config.py +++ b/src/omnibase_core/models/delegation/wire/model_bifrost_delegation_config.py @@ -156,8 +156,19 @@ class ModelDelegationBackendConfig(BaseModel): default=None, description="Optional static HTTP headers required by the backend provider.", ) - tier: Literal["local", "frontier_api"] = Field( - ..., description="Routing tier: 'local' or 'frontier_api'." + tier: Literal[ + "local", "frontier_api", "cheap_cloud", "cheap_frontier", "cli_agents" + ] = Field( + ..., + description=( + "Routing tier. Values verified against live bifrost_delegation.yaml and " + "routing_tiers.yaml (OMN-12663): " + "'local' = vLLM on .201; " + "'frontier_api' = Claude API; " + "'cheap_cloud' = OpenRouter/Gemini/GLM; " + "'cheap_frontier' = free-tier frontier models (OMN-12492); " + "'cli_agents' = subprocess-dispatched CLI agents (OMN-10137)." + ), ) timeout_ms: int = Field( default=30000, diff --git a/src/omnibase_core/topics.py b/src/omnibase_core/topics.py index 3bf7b062e8..558196d75a 100644 --- a/src/omnibase_core/topics.py +++ b/src/omnibase_core/topics.py @@ -486,6 +486,44 @@ class TopicBase(StrEnum): remote A2A peer. (OMN-9637) """ + # ========================================================================== + # Delegation inference pipeline topics (OMN-12663) + # Live runtime topics confirmed by D3 trace (OMN-12642): the omnibase-infra + # namespace is the authoritative runtime namespace for the inference + # request/response and delegation completion/failure events. + # ========================================================================== + DELEGATION_COMPLETED_INFRA = "onex.evt.omnibase-infra.delegation-completed.v1" + """Emitted by node_delegation_orchestrator when a delegation run completes successfully. + + Producer: node_delegation_orchestrator (omnibase_infra runtime). + Confirmed in live D3 trace (OMN-12642, stability-test lane). + """ + + DELEGATION_FAILED_INFRA = "onex.evt.omnibase-infra.delegation-failed.v1" + """Emitted by node_delegation_orchestrator when a delegation run fails at any stage. + + Producer: node_delegation_orchestrator (omnibase_infra runtime). + Confirmed in live D3 trace (OMN-12642, stability-test lane). + """ + + DELEGATION_INFERENCE_REQUEST = ( + "onex.cmd.omnibase-infra.delegation-inference-request.v1" + ) + """Command published by the delegation orchestrator to invoke LLM inference. + + Consumed by node_llm_delegation_call_effect (effects runtime). + Confirmed in live D3 trace (OMN-12642): raw Kafka payload captured with this + exact topic name on stability-test lane. + """ + + DELEGATION_INFERENCE_RESPONSE = "onex.evt.omnibase-infra.inference-response.v1" + """Event published by node_llm_delegation_call_effect after LLM inference completes. + + Published for both success and error outcomes (D4 defect: error_message field + indicates failure; no separate error topic exists as of OMN-12643). + Confirmed in live D3 trace (OMN-12642): response captured on this exact topic. + """ + # ========================================================================== # Team lifecycle topics (OMN-7026) # Unified event schema for all dispatch surfaces (team_worker, diff --git a/tests/unit/models/delegation/wire/test_delegation_wire_models.py b/tests/unit/models/delegation/wire/test_delegation_wire_models.py index cb7c40cff5..ad67f0f2bc 100644 --- a/tests/unit/models/delegation/wire/test_delegation_wire_models.py +++ b/tests/unit/models/delegation/wire/test_delegation_wire_models.py @@ -368,6 +368,29 @@ def test_rejects_invalid_bifrost_wire_literals(self) -> None: with pytest.raises(ValidationError): ModelDelegationBackendConfig(backend_id="local_qwen3", tier="unknown") + def test_all_live_tier_values_accepted(self) -> None: + """All tier values present in live bifrost_delegation.yaml must be valid (OMN-12663). + + Verified against bifrost_delegation.yaml and routing_tiers.yaml in omnimarket + and omnibase_infra; values confirmed in D3 trace (OMN-12642). + """ + live_tiers = ( + "local", + "frontier_api", + "cheap_cloud", + "cheap_frontier", + "cli_agents", + ) + for tier in live_tiers: + backend = ModelDelegationBackendConfig(backend_id=f"test-{tier}", tier=tier) + assert backend.tier == tier, f"tier={tier!r} round-trip failed" + + def test_previously_missing_tiers_now_accepted(self) -> None: + """cheap_cloud, cheap_frontier, and cli_agents were the three missing values (OMN-12663).""" + for tier in ("cheap_cloud", "cheap_frontier", "cli_agents"): + backend = ModelDelegationBackendConfig(backend_id=f"test-{tier}", tier=tier) + assert backend.tier == tier + @pytest.mark.unit class TestModelTaskDelegatedEvent: diff --git a/tests/unit/test_topic_base_delegation_infra.py b/tests/unit/test_topic_base_delegation_infra.py new file mode 100644 index 0000000000..c03c23b8d1 --- /dev/null +++ b/tests/unit/test_topic_base_delegation_infra.py @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: 2025 OmniNode.ai Inc. +# SPDX-License-Identifier: MIT + +"""TopicBase coverage for omnibase-infra delegation inference pipeline topics (OMN-12663). + +Blocker 1 fix: TopicBase was missing the four omnibase-infra-namespace delegation +topics used by the live runtime (confirmed by D3 trace in OMN-12642). +""" + +from __future__ import annotations + +import pytest + +from omnibase_core.topics import TopicBase, build_topic + +pytestmark = pytest.mark.unit + + +def test_delegation_completed_infra_topic_value() -> None: + assert ( + TopicBase.DELEGATION_COMPLETED_INFRA + == "onex.evt.omnibase-infra.delegation-completed.v1" + ) + + +def test_delegation_failed_infra_topic_value() -> None: + assert ( + TopicBase.DELEGATION_FAILED_INFRA + == "onex.evt.omnibase-infra.delegation-failed.v1" + ) + + +def test_delegation_inference_request_topic_value() -> None: + assert ( + TopicBase.DELEGATION_INFERENCE_REQUEST + == "onex.cmd.omnibase-infra.delegation-inference-request.v1" + ) + + +def test_delegation_inference_response_topic_value() -> None: + assert ( + TopicBase.DELEGATION_INFERENCE_RESPONSE + == "onex.evt.omnibase-infra.inference-response.v1" + ) + + +def test_delegation_infra_topics_pass_canonical_validation() -> None: + """All four new topics must satisfy the canonical ONEX topic format check.""" + new_topics = [ + TopicBase.DELEGATION_COMPLETED_INFRA, + TopicBase.DELEGATION_FAILED_INFRA, + TopicBase.DELEGATION_INFERENCE_REQUEST, + TopicBase.DELEGATION_INFERENCE_RESPONSE, + ] + for topic in new_topics: + result = build_topic(topic) + assert result == topic, f"build_topic round-trip failed for {topic!r}" + + +def test_delegation_infra_topics_are_str_enum_members() -> None: + """Each new topic must be a member of TopicBase (StrEnum).""" + assert ( + "onex.evt.omnibase-infra.delegation-completed.v1" + in TopicBase._value2member_map_ + ) + assert ( + "onex.evt.omnibase-infra.delegation-failed.v1" in TopicBase._value2member_map_ + ) + assert ( + "onex.cmd.omnibase-infra.delegation-inference-request.v1" + in TopicBase._value2member_map_ + ) + assert ( + "onex.evt.omnibase-infra.inference-response.v1" in TopicBase._value2member_map_ + )