@@ -52,6 +52,27 @@ def filter(self, record: logging.LogRecord) -> bool:
5252load_dotenv () # load from cwd (covers running inside the KB dir)
5353
5454
55+ _KNOWN_PROVIDER_KEYS = (
56+ "OPENAI_API_KEY" , "ANTHROPIC_API_KEY" , "GEMINI_API_KEY" ,
57+ "DEEPSEEK_API_KEY" , "MISTRAL_API_KEY" , "MOONSHOT_API_KEY" ,
58+ "ZHIPUAI_API_KEY" , "DASHSCOPE_API_KEY" ,
59+ )
60+
61+
62+ def _extract_provider (model : str ) -> str | None :
63+ """Extract the LiteLLM provider name from a model string.
64+
65+ ``model`` uses ``provider/model`` LiteLLM format.
66+ OpenAI models can omit the prefix; default to ``"openai"``.
67+ """
68+ model = model .strip ()
69+ if not model :
70+ return None
71+ if "/" in model :
72+ return model .split ("/" )[0 ].lower ()
73+ return "openai"
74+
75+
5576def _setup_llm_key (kb_dir : Path | None = None ) -> None :
5677 """Set LiteLLM API key from LLM_API_KEY env var if present.
5778
@@ -62,6 +83,8 @@ def _setup_llm_key(kb_dir: Path | None = None) -> None:
6283
6384 Also propagates to provider-specific env vars (OPENAI_API_KEY, etc.)
6485 so that the Agents SDK litellm provider can pick them up.
86+ Provider is auto-detected from the KB config when available; otherwise
87+ a common provider set is used as a fallback.
6588 """
6689 if kb_dir is not None :
6790 env_file = kb_dir / ".env"
@@ -74,9 +97,23 @@ def _setup_llm_key(kb_dir: Path | None = None) -> None:
7497 load_dotenv (global_env , override = False )
7598
7699 api_key = os .environ .get ("LLM_API_KEY" , "" )
100+
101+ # Try to resolve the active provider from the KB config
102+ provider : str | None = None
103+ if kb_dir is not None :
104+ config_path = kb_dir / ".openkb" / "config.yaml"
105+ if config_path .exists ():
106+ config = load_config (config_path )
107+ model = config .get ("model" , "" )
108+ provider = _extract_provider (str (model ))
109+
77110 if not api_key :
78111 # Check if any provider key is already set
79- has_key = any (os .environ .get (k ) for k in ("OPENAI_API_KEY" , "ANTHROPIC_API_KEY" , "GEMINI_API_KEY" ))
112+ check_keys = (
113+ (f"{ provider .upper ()} _API_KEY" ,) if provider
114+ else _KNOWN_PROVIDER_KEYS
115+ )
116+ has_key = any (os .environ .get (k ) for k in check_keys )
80117 if not has_key :
81118 click .echo (
82119 "Warning: No LLM API key found. Set one of:\n "
@@ -86,7 +123,16 @@ def _setup_llm_key(kb_dir: Path | None = None) -> None:
86123 )
87124 else :
88125 litellm .api_key = api_key
89- for env_var in ("OPENAI_API_KEY" , "ANTHROPIC_API_KEY" , "GEMINI_API_KEY" ):
126+
127+ # Dynamically set the provider-specific env var when possible
128+ if provider :
129+ provider_env = f"{ provider .upper ()} _API_KEY"
130+ if not os .environ .get (provider_env ):
131+ os .environ [provider_env ] = api_key
132+
133+ # Fallback: also set common provider keys so multi-provider
134+ # configs (e.g. PageIndex Cloud) still work
135+ for env_var in _KNOWN_PROVIDER_KEYS :
90136 if not os .environ .get (env_var ):
91137 os .environ [env_var ] = api_key
92138
@@ -462,6 +508,7 @@ def init(model, language):
462508 click .echo (" OpenAI: gpt-5.4-mini, gpt-5.4" )
463509 click .echo (" Anthropic: anthropic/claude-sonnet-4-6, anthropic/claude-opus-4-6" )
464510 click .echo (" Gemini: gemini/gemini-3.1-pro-preview, gemini/gemini-3-flash-preview" )
511+ click .echo (" DeepSeek: deepseek/deepseek-v4-flash, deepseek/deepseek-v4-pro" )
465512 click .echo (" Others: see https://docs.litellm.ai/docs/providers" )
466513 click .echo ()
467514 if model is None and _stdin_is_tty ():
0 commit comments