from __future__ import annotations from .shared import * class LLMControlPlaneRoutingMixin: def _mixed_routing_enabled(self) -> bool: return _env_bool("LLM_MIXED_ROUTING_ENABLED", False) def _control_plane_routing_enabled(self) -> bool: return _env_bool("CONTROL_PLANE_ROUTING_ENABLED", False) def _control_plane_only(self) -> bool: return _env_bool("CONTROL_PLANE_ONLY", False) def _ensure_control_plane_engine(self, engine: dict[str, Any]) -> dict[str, Any]: runtime = dict(engine or {}) runtime["source_provider"] = str(runtime.get("source_provider") or runtime.get("provider") or "").strip().lower() return runtime def _control_plane_rules_path(self) -> str: return str(resolve_model_config_path()) def _load_control_plane_routing_bundle(self) -> dict[str, Any]: now = time.time() if self._control_plane_routing_cache and self._control_plane_routing_cache[0] > now: return dict(self._control_plane_routing_cache[1]) path = Path(self._control_plane_rules_path()) bundle: dict[str, Any] = load_model_config(path=path) self._control_plane_routing_cache = (now + CONTROL_PLANE_ROUTING_CACHE_TTL_SECONDS, dict(bundle)) return dict(bundle) @staticmethod def _rule_matches_function(rule: dict[str, Any], function_name: str) -> bool: return rule_matches_function(rule, function_name) def _match_control_plane_rule( self, function_name: str, *, tier_filter: Optional[set[str]] = None, ) -> Optional[dict[str, Any]]: if not self._control_plane_routing_enabled(): return None bundle = self._load_control_plane_routing_bundle() return find_matching_rule( function_name, tier_filter=tier_filter, bundle=bundle, ) def _resolve_control_plane_engine( self, *, function_name: str, engines: list[dict[str, Any]], active_engine: dict[str, Any], slot_bundle: dict[str, Any] | None = None, routing_meta: dict[str, Any] | None = None, ) -> Optional[dict[str, Any]]: meta = _normalize_routing_meta(routing_meta) tier_filter: set[str] = {"low", "high"} explicit_tier = _optional_tier_alias( meta.get("planned_tier") or meta.get("tier_alias") or meta.get("executed_tier") ) if ( str(meta.get("routing_decision") or "").strip().lower() == "force_low_first" and explicit_tier in {"low", "high"} ): tier_filter = {explicit_tier} rule = self._match_control_plane_rule(function_name, tier_filter=tier_filter) if not rule: return None routed = self._resolve_engine_from_rule( rule=rule, engines=engines, active_engine=active_engine, slot_bundle=slot_bundle, ) if routed is None: return None bundle = self._load_control_plane_routing_bundle() config_snapshot = build_routing_config_snapshot(bundle=bundle) tier_alias = str(rule.get("tier") or "").strip().lower() or "low" routed = _merge_engine_routing_meta( routed, tier_alias=tier_alias, planned_tier=tier_alias, executed_tier=tier_alias, route_source="default", route_rule_name=str(rule.get("name") or "").strip(), rule_priority=int(rule.get("priority") or 0), routing_decision="rule_match", routing_config_version=config_snapshot.get("routing_config_version"), routing_config_updated_at=config_snapshot.get("routing_config_updated_at"), ) _runtime_log( "PMFlow 本地路由层路由", ( "规则命中:" f"function={function_name}, {_routing_meta_log_text(_read_engine_routing_meta(routed))}" ), ) return routed def _resolve_engine_from_rule( self, *, rule: dict[str, Any], engines: list[dict[str, Any]], active_engine: dict[str, Any], slot_bundle: dict[str, Any] | None = None, ) -> Optional[dict[str, Any]]: tier = str(rule.get("tier") or "").strip().lower() provider_raw = str(rule.get("provider") or "").strip().lower() engine_id = str(rule.get("engine_id") or "").strip() model_override = str(rule.get("model") or "").strip() base_url_override = str(rule.get("base_url") or "").strip().rstrip("/") routed: Optional[dict[str, Any]] = None if engine_id: for item in engines: if str(item.get("id") or "").strip() == engine_id: routed = self._normalize_engine_runtime(item) break if routed is None and tier in {"high", "low"}: routed = self._resolve_tier_engine( tier=tier, engines=engines, active_engine=active_engine, slot_bundle=slot_bundle, ) if routed is None and provider_raw: try: provider = _normalize_provider(provider_raw) except Exception: provider = "" if provider: for item in engines: if str(item.get("provider") or "").strip().lower() == provider: routed = self._normalize_engine_runtime(item) break if routed is None: return None if model_override and not self._slot_binding_exists(slot_bundle=slot_bundle, tier=tier): routed["model"] = model_override if base_url_override and not self._slot_binding_exists(slot_bundle=slot_bundle, tier=tier): routed["base_url"] = base_url_override return routed @staticmethod def _slot_binding_exists(*, slot_bundle: dict[str, Any] | None, tier: str) -> bool: slots = {} if isinstance(slot_bundle, dict): active = slot_bundle.get("active") if isinstance(slot_bundle.get("active"), dict) else {} if isinstance(active.get("slots"), dict): slots = active["slots"] elif isinstance(slot_bundle.get("slots"), dict): slots = slot_bundle["slots"] slot = slots.get(str(tier or "").strip().lower()) return isinstance(slot, dict) and bool(str(slot.get("primary_engine_id") or "").strip()) def _resolve_function_tier(self, function_name: str, routing_meta: dict[str, Any] | None = None) -> str: meta = _normalize_routing_meta(routing_meta) explicit_tier = _optional_tier_alias( meta.get("planned_tier") or meta.get("tier_alias") or meta.get("executed_tier") ) if explicit_tier: return explicit_tier fn = str(function_name or "").strip().lower() if not fn: return str(os.getenv("LLM_ROUTING_DEFAULT_TIER", "low") or "low").strip().lower() bundle = self._load_control_plane_routing_bundle() rule = find_matching_rule(fn, tier_filter={"low", "high"}, bundle=bundle) if isinstance(rule, dict): configured_tier = str(rule.get("tier") or "").strip().lower() if configured_tier in {"low", "high"}: return configured_tier default_tier = str(os.getenv("LLM_ROUTING_DEFAULT_TIER", "low") or "low").strip().lower() if default_tier in {"low", "high"}: return default_tier return "high" if self._mixed_routing_enabled() else "low"