Coverage for agentos/llm/factory.py: 30%
23 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-02 09:59 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-02 09:59 +0800
1"""
2LLM Provider 工厂 — 按名称/配置创建 Provider 实例。
3v1.3.36: DeepSeek + Anthropic 硬注册(纯 httpx 实现,零 SDK 依赖)。
5用法:
6 from agentos.llm.factory import create_provider
8 provider = create_provider("openai", model="gpt-4o", api_key="sk-...")
9 result = provider.chat([Message(...), Message(...)])
10"""
12from __future__ import annotations
14import os
15from typing import Any
17from agentos.llm.base import LLMProvider
19__all__ = ["create_provider"]
21_PROVIDER_REGISTRY: dict[str, tuple[str, str]] = {
22 "openai": ("agentos.llm.openai_provider", "OpenAIProvider"),
23 "deepseek": ("agentos.llm.deepseek_provider", "DeepSeekProvider"),
24 "anthropic": ("agentos.llm.anthropic_provider", "AnthropicProvider"),
25 "ollama": ("agentos.llm.ollama_provider", "OllamaProvider"),
26 "pangu": ("agentos.llm.pangu_provider", "PanguProvider"),
27}
30def create_provider(
31 name: str = "openai",
32 *,
33 model: str = "",
34 api_key: str = "",
35 base_url: str = "",
36 **extra: Any,
37) -> LLMProvider:
38 """
39 创建 LLM Provider 实例。
41 Args:
42 name: 提供商名称 — "openai" / "deepseek" / "anthropic"。
43 model: 模型名称。openai: gpt-4o-mini, deepseek: deepseek-chat, anthropic: claude-sonnet-4-20250514。
44 api_key: API Key。不传则从环境变量读取。
45 base_url: 自定义端点。
47 Returns:
48 LLMProvider 实例。
49 """
50 if name not in _PROVIDER_REGISTRY:
51 raise ValueError(
52 f"Unknown provider: '{name}'. Available: {sorted(_PROVIDER_REGISTRY)}"
53 )
55 module_path, class_name = _PROVIDER_REGISTRY[name]
57 import importlib
58 mod = importlib.import_module(module_path)
59 cls = getattr(mod, class_name)
61 # Auto-detect API key from env
62 if not api_key:
63 env_var_map = {
64 "openai": "OPENAI_API_KEY",
65 "deepseek": "DEEPSEEK_API_KEY",
66 "anthropic": "ANTHROPIC_API_KEY",
67 "ollama": "OLLAMA_API_KEY",
68 "pangu": "PANGU_API_KEY",
69 }
70 api_key = os.getenv(env_var_map.get(name, ""), "")
72 # Default models
73 if not model:
74 defaults = {
75 "openai": "gpt-4o-mini",
76 "deepseek": "deepseek-chat",
77 "anthropic": "claude-sonnet-5-20250630",
78 "ollama": "qwen2.5:7b",
79 "pangu": "pangu-4",
80 }
81 model = defaults.get(name, "")
83 kwargs: dict[str, Any] = {}
84 if base_url:
85 kwargs["base_url"] = base_url
86 return cls(model=model, api_key=api_key, **kwargs, **extra)