From 006e1594eb8f22cef8f8523e462cb15a037e0a9a Mon Sep 17 00:00:00 2001 From: Safi Date: Sat, 30 May 2026 13:17:13 +0100 Subject: [PATCH] fix extract_files_direct backend default: auto-detect instead of kimi (closes #1086) Co-Authored-By: Claude Sonnet 4.6 --- README.md | 1 + graphify/llm.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 360023ec..a25195af 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,7 @@ These are only needed for **headless / CI extraction** (`graphify extract`). Whe - **Code files** — processed locally via tree-sitter. Nothing leaves your machine. - **Video / audio** — transcribed locally with faster-whisper. Nothing leaves your machine. - **Docs, PDFs, images** — sent to your AI assistant for semantic extraction (via the `/graphify` skill, using whatever model your IDE session runs). Headless `graphify extract` requires `GEMINI_API_KEY` / `GOOGLE_API_KEY` (Gemini), `MOONSHOT_API_KEY` (Kimi), `ANTHROPIC_API_KEY` (Claude), `OPENAI_API_KEY` (OpenAI), `DEEPSEEK_API_KEY` (DeepSeek), a running Ollama instance (`OLLAMA_BASE_URL`), AWS credentials via the standard provider chain (Bedrock - no API key needed, uses IAM), or the `claude` CLI binary (Claude Code - no API key needed, uses your Claude subscription). The `--dedup-llm` flag uses the same key. +- **Data residency** — `graphify extract` auto-detects which provider to use based on which API key is set (priority: Gemini → Kimi → Claude → OpenAI → DeepSeek → Bedrock → Ollama). For code with data-residency requirements, use `--backend ollama` (fully local) or pass an explicit `--backend` flag. Kimi (`MOONSHOT_API_KEY`) routes to Moonshot AI servers in China. - No telemetry, no usage tracking, no analytics. --- diff --git a/graphify/llm.py b/graphify/llm.py index 4807500d..8aba58b6 100644 --- a/graphify/llm.py +++ b/graphify/llm.py @@ -629,7 +629,7 @@ def _call_bedrock(model: str, user_message: str, max_tokens: int = 8192, *, deep def extract_files_direct( files: list[Path], - backend: str = "kimi", + backend: str | None = None, api_key: str | None = None, model: str | None = None, root: Path = Path("."), @@ -639,8 +639,17 @@ def extract_files_direct( """Extract semantic nodes/edges from a list of files using the given backend. Returns dict with nodes, edges, hyperedges, input_tokens, output_tokens. - Raises ValueError for unknown backends. Raises ImportError if SDK missing. + Raises ValueError for unknown backends or when no API key is configured. + Raises ImportError if SDK missing. """ + if backend is None: + backend = detect_backend() + if backend is None: + raise ValueError( + "No LLM backend configured. Set one of: GEMINI_API_KEY, ANTHROPIC_API_KEY, " + "OPENAI_API_KEY, DEEPSEEK_API_KEY, MOONSHOT_API_KEY, OLLAMA_BASE_URL, " + "or AWS credentials. Pass backend= explicitly to select a provider." + ) if backend not in BACKENDS: raise ValueError(f"Unknown backend {backend!r}. Available: {sorted(BACKENDS)}")