From b21d6acc8e2ada5850f675f78c9491cd71e3c270 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Sat, 25 Apr 2026 16:01:05 -0700 Subject: [PATCH] feat: add detect_byok() public utility to cloud_session, bump v0.16.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted from kiwi/avocet where it was duplicated. Reads llm.yaml via the same path LLMRouter uses — products can now import detect_byok from cf-core instead of maintaining their own copy. --- circuitforge_core/__init__.py | 2 +- circuitforge_core/cloud_session/__init__.py | 26 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/circuitforge_core/__init__.py b/circuitforge_core/__init__.py index 745614a..45335d8 100644 --- a/circuitforge_core/__init__.py +++ b/circuitforge_core/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.16.0" +__version__ = "0.16.1" try: from circuitforge_core.community import CommunityDB, CommunityPost, SharedStore diff --git a/circuitforge_core/cloud_session/__init__.py b/circuitforge_core/cloud_session/__init__.py index c37fd11..a90d212 100644 --- a/circuitforge_core/cloud_session/__init__.py +++ b/circuitforge_core/cloud_session/__init__.py @@ -312,3 +312,29 @@ class CloudSessionFactory: return session return _check + + +# ── BYOK detection ──────────────────────────────────────────────────────────── + +def detect_byok(config_path: Path | None = None) -> bool: + """Return True if at least one enabled non-vision LLM backend is configured. + + Reads the shared llm.yaml that LLMRouter uses. Local (Ollama, vLLM) and + API-key backends both count — the policy is "user is supplying compute", + regardless of where that compute lives. + + Args: + config_path: Override the default config location. Useful in tests. + """ + import yaml + if config_path is None: + config_path = Path.home() / ".config" / "circuitforge" / "llm.yaml" + try: + with open(config_path) as f: + cfg = yaml.safe_load(f) or {} + return any( + b.get("enabled", True) and b.get("type") != "vision_service" + for b in cfg.get("backends", {}).values() + ) + except Exception: + return False