Files

1 line
32 KiB
JSON

{"repo": "andrewyng/aisuite", "files": {"platform/coworker/providers/registry.py": {"cb29165b00f719cceae6a82ed4621cbcb79aaaf7": {"t": 1785674158.2546403, "n": 15952, "h": "c7e392184b3e4c58", "c": "\"\"\"Model-provider registry — descriptors + a factory, mirroring the connector\n(`connectors/descriptors.py`) and web-search (`web/providers.py`) patterns.\n\nA `ProviderDescriptor` declares a provider's UI config `fields` (rendered dynamically by the\nGUI, same `to_dict()` shape connectors use) and a `build(profile, secrets)` factory that returns\na `ProviderClient`. The `ProviderRouter` selects a descriptor by the `provider:` prefix of a\nmodel string and builds (and caches) its client from the matching SecretStore profile.\n\nToday: `openai` (the default, with an optional custom endpoint that covers Azure OpenAI's\n`/openai/v1` and any OpenAI-compliant gateway), `anthropic` (native Messages API via\n`AnthropicProvider`), `gemini` (native Google GenAI API via `GeminiProvider`), and `ollama`\n(local, OpenAI-compatible `/v1`). Bedrock/Vertex auth for Claude is future work.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom dataclasses import dataclass, field\nfrom typing import Any, Callable, Optional\n\nfrom .anthropic_provider import AnthropicProvider\nfrom .base import ProviderClient\nfrom .gemini_provider import GeminiProvider\nfrom .openai_provider import OpenAIProvider\n\nDEFAULT_OLLAMA_URL = \"http://localhost:11434\"\n\n\n@dataclass(frozen=True)\nclass ProviderField:\n \"\"\"One config input for a provider, rendered by the GUI (mirrors connectors' `Field`).\"\"\"\n\n key: str\n label: str\n secret: bool = False\n required: bool = True\n help: str = \"\"\n placeholder: str = \"\"\n # Pre-filled (still editable) form value — e.g. an OpenAI-compatible vendor's official\n # endpoint, so the user only has to paste a key. Distinct from `placeholder` (grey hint).\n default: str = \"\"\n\n def to_dict(self) -> dict[str, Any]:\n return {\n \"key\": self.key,\n \"label\": self.label,\n \"secret\": self.secret,\n \"required\": self.required,\n \"help\": self.help,\n \"placeholder\": self.placeholder,\n \"default\": self.default,\n }\n\n\n@dataclass(frozen=True)\nclass ProviderDescriptor:\n \"\"\"A model provider: its UI fields + a factory that builds its `ProviderClient`.\"\"\"\n\n name: str\n title: str\n needs_key: bool\n fields: list[ProviderField]\n build: Callable[[dict[str, Any], Any], ProviderClient] = field(repr=False)\n recommended_model: Optional[str] = (\n None # pre-filled in the UI; auto-added on configure\n )\n env_key: Optional[str] = (\n None # env var that can supply the API key (e.g. ANTHROPIC_API_KEY)\n )\n # One-line note under the provider title (e.g. \"Connects through X's OpenAI-compatible API\").\n blurb: str = \"\"\n\n def to_dict(self) -> dict[str, Any]:\n return {\n \"name\": self.name,\n \"title\": self.title,\n \"needs_key\": self.needs_key,\n \"fields\": [f.to_dict() for f in self.fields],\n \"recommended_model\": self.recommended_model,\n \"blurb\": self.blurb,\n }\n\n\ndef _normalize_ollama_url(url: Optional[str]) -> str:\n \"\"\"Accept `http://host:11434` or `.../v1` and return an OpenAI-compatible base URL.\n\n Ollama serves its OpenAI-compatible API under `/v1`; the native API lives at the root, so we\n always target `<root>/v1`.\n \"\"\"\n base = (url or DEFAULT_OLLAMA_URL).strip().rstrip(\"/\")\n if not base:\n base = DEFAULT_OLLAMA_URL\n if not base.endswith(\"/v1\"):\n base = base + \"/v1\"\n return base\n\n\ndef _build_openai(profile: dict[str, Any], secrets: Any) -> ProviderClient:\n # Key resolution stays in OpenAIProvider/resolve_api_key (explicit → env → SecretStore),\n # so we just hand it the SecretStore. An optional custom endpoint (Azure OpenAI /openai/v1,\n # OpenRouter, vLLM, …) comes from the stored profile.\n base_url = ((profile or {}).get(\"base_url\") or \"\").strip() or None\n return OpenAIProvider(secrets=secrets, base_url=base_url)\n\n\ndef _build_anthropic(profile: dict[str, Any], secrets: Any) -> ProviderClient:\n # Key resolution stays in AnthropicProvider/resolve_api_key (explicit → env → SecretStore),\n # deferred to first call so the provider can be built before a key exists.\n api_key = ((profile or {}).get(\"api_key\") or \"\").strip() or None\n return AnthropicProvider(api_key=api_key, secrets=secrets)\n\n\ndef _build_gemini(profile: dict[str, Any], secrets: Any) -> ProviderClient:\n # Same deferred-key contract as anthropic (GeminiProvider/resolve_api_key).\n api_key = ((profile or {}).get(\"api_key\") or \"\").strip() or None\n return GeminiProvider(api_key=api_key, secrets=secrets)\n\n\ndef _build_ollama(profile: dict[str, Any], secrets: Any) -> ProviderClient:\n # Ollama's OpenAI-compatible endpoint ignores the key but the SDK requires a non-empty\n # string, so we pass a placeholder. `base_url` comes from the stored profile (or the default).\n base_url = _normalize_ollama_url((profile or {}).get(\"base_url\"))\n return OpenAIProvider(api_key=\"ollama\", base_url=base_url)\n\n\ndef _openai_compat(vendor: str, default_base_url: str, env_key: Optional[str] = None):\n \"\"\"Builder factory for vendors reached through their OpenAI-compatible API (Z AI, DeepSeek,\n Kimi, MiniMax, Qwen, xAI, Mistral). The key is resolved from the vendor's OWN profile (or its\n env var) — deliberately NOT from the OpenAI env/SecretStore fallback, so a configured OpenAI\n key is never silently sent to a different vendor's endpoint. Missing key ⇒ fail fast with a\n vendor-named error (these are only built on demand, when one of their models is selected).\n \"\"\"\n\n def build(profile: dict[str, Any], secrets: Any) -> ProviderClient:\n base_url = ((profile or {}).get(\"base_url\") or \"\").strip() or default_base_url\n api_key = ((profile or {}).get(\"api_key\") or \"\").strip() or (\n os.environ.get(env_key, \"\").strip() if env_key else \"\"\n )\n if not api_key:\n raise RuntimeError(\n f\"No {vendor} API key configured — add it in Settings ▸ Models.\"\n )\n return OpenAIProvider(api_key=api_key, base_url=base_url)\n\n return build\n\n\ndef _compat(\n name: str,\n title: str,\n *,\n base_url: str,\n recommended_model: str,\n env_key: str,\n endpoint_help: str = \"\",\n) -> ProviderDescriptor:\n \"\"\"Descriptor for an OpenAI-compatible vendor: key + a prefilled, editable endpoint.\"\"\"\n vendor = title.split(\" (\")[0]\n return ProviderDescriptor(\n name=name,\n title=title,\n needs_key=True,\n fields=[\n ProviderField(\n \"api_key\",\n f\"{vendor} API key\",\n secret=True,\n ),\n ProviderField(\n \"base_url\",\n \"Endpoint\",\n required=False,\n default=base_url,\n placeholder=base_url,\n help=endpoint_help\n or f\"Prefilled with {vendor}'s official endpoint; edit only for a regional or proxy variant.\",\n ),\n ],\n build=_openai_compat(vendor, base_url, env_key),\n recommended_model=recommended_model,\n env_key=env_key,\n blurb=f\"Uses {vendor}'s OpenAI-compatible API — the endpoint is prefilled, just add your key.\",\n )\n\n\nDESCRIPTORS: list[ProviderDescriptor] = [\n ProviderDescriptor(\n name=\"openai\",\n title=\"OpenAI\",\n needs_key=True,\n fields=[\n ProviderField(\n \"api_key\",\n \"OpenAI API key\",\n secret=True,\n placeholder=\"sk-…\",\n ),\n ProviderField(\n \"base_url\",\n \"Custom endpoint (optional)\",\n secret=False,\n required=False,\n placeholder=\"https://…/openai/v1\",\n help=\"For Azure OpenAI, OpenRouter, vLLM, or any OpenAI-compliant server. Leave blank for api.openai.com.\",\n ),\n ],\n build=_build_openai,\n recommended_model=\"gpt-5.6-sol\",\n env_key=\"OPENAI_API_KEY\",\n ),\n ProviderDescriptor(\n name=\"anthropic\",\n title=\"Claude (Anthropic)\",\n needs_key=True,\n fields=[\n ProviderField(\n \"api_key\",\n \"Anthropic API key\",\n secret=True,\n placeholder=\"sk-ant-…\",\n ),\n ],\n build=_build_anthropic,\n recommended_model=\"claude-fable-5\",\n env_key=\"ANTHROPIC_API_KEY\",\n ),\n ProviderDescriptor(\n name=\"gemini\",\n title=\"Gemini (Google)\",\n needs_key=True,\n fields=[\n ProviderField(\n \"api_key\",\n \"Gemini API key\",\n secret=True,\n placeholder=\"AIza…\",\n ),\n ],\n build=_build_gemini,\n recommended_model=\"gemini-2.5-flash\",\n env_key=\"GEMINI_API_KEY\",\n ),\n # OpenAI-compatible vendors, listed as first-class providers so users don't need to know the\n # \"point the OpenAI slot at a different endpoint\" trick (owner call, 2026-07-04). Each keeps\n # its own key profile; the endpoint is prefilled and editable (regional variants in `help`).\n _compat(\n \"zai\",\n \"Z AI (GLM)\",\n base_url=\"https://api.z.ai/api/paas/v4\",\n recommended_model=\"glm-5.2\",\n env_key=\"ZAI_API_KEY\",\n endpoint_help=\"Prefilled with Z AI's international endpoint. China mainland: https://open.bigmodel.cn/api/paas/v4\",\n ),\n _compat(\n \"deepseek\",\n \"DeepSeek\",\n base_url=\"https://api.deepseek.com\",\n recommended_model=\"deepseek-v4-flash\",\n env_key=\"DEEPSEEK_API_KEY\",\n ),\n _compat(\n \"kimi\",\n \"Kimi (Moonshot AI)\",\n base_url=\"https://api.moonshot.ai/v1\",\n recommended_model=\"kimi-k2.6\",\n env_key=\"MOONSHOT_API_KEY\",\n endpoint_help=\"Prefilled with Moonshot's international endpoint. China mainland: https://api.moonshot.cn/v1\",\n ),\n _compat(\n \"minimax\",\n \"MiniMax\",\n base_url=\"https://api.minimax.io/v1\",\n recommended_model=\"MiniMax-M2.5\",\n env_key=\"MINIMAX_API_KEY\",\n ),\n _compat(\n \"qwen\",\n \"Qwen (Alibaba)\",\n base_url=\"https://dashscope-intl.aliyuncs.com/compatible-mode/v1\",\n recommended_model=\"qwen3-max\",\n env_key=\"DASHSCOPE_API_KEY\",\n endpoint_help=\"Prefilled with Alibaba Model Studio's international endpoint. China (Beijing): https://dashscope.aliyuncs.com/compatible-mode/v1\",\n ),\n _compat(\n \"xai\",\n \"xAI (Grok)\",\n base_url=\"https://api.x.ai/v1\",\n recommended_model=\"grok-4.3\",\n env_key=\"XAI_API_KEY\",\n ),\n _compat(\n \"mistral\",\n \"Mistral\",\n base_url=\"https://api.mistral.ai/v1\",\n recommended_model=\"mistral-large-latest\",\n env_key=\"MISTRAL_API_KEY\",\n ),\n # Resellers: many labs' models behind one key, using THEIR model namespaces (the curated\n # ids + display labels live in providers/matrix.py). TODO: add Groq and OpenRouter here\n # (+ their matrix rows) once the current provider surface is tested — deliberately\n # deferred to bound how much needs verifying at once (owner call, 2026-07-04).\n _compat(\n \"together\",\n \"Together AI\",\n base_url=\"https://api.together.xyz/v1\",\n recommended_model=\"zai-org/GLM-5.2\",\n env_key=\"TOGETHER_API_KEY\",\n ),\n _compat(\n \"fireworks\",\n \"Fireworks AI\",\n base_url=\"https://api.fireworks.ai/inference/v1\",\n recommended_model=\"accounts/fireworks/models/glm-5p2\",\n env_key=\"FIREWORKS_API_KEY\",\n ),\n ProviderDescriptor(\n name=\"ollama\",\n title=\"Ollama (local models)\",\n needs_key=False,\n fields=[\n ProviderField(\n \"base_url\",\n \"Ollama server URL\",\n secret=False,\n required=False,\n placeholder=DEFAULT_OLLAMA_URL,\n help=\"Where `ollama serve` is listening. The OpenAI-compatible /v1 path is added automatically.\",\n ),\n ],\n build=_build_ollama,\n # Reliable native tool-calling + strong coding quality (verified). Pull with\n # `ollama pull qwen3-coder:30b`.\n recommended_model=\"qwen3-coder:30b\",\n ),\n]\n\n_BY_NAME = {d.name: d for d in DESCRIPTORS}\n\n\ndef provider_descriptors() -> list[ProviderDescriptor]:\n return list(DESCRIPTORS)\n\n\ndef provider_names() -> list[str]:\n return [d.name for d in DESCRIPTORS]\n\n\ndef get_descriptor(name: str) -> Optional[ProviderDescriptor]:\n return _BY_NAME.get(name)\n\n\ndef build_provider_client(\n name: str, profile: dict[str, Any], secrets: Any\n) -> ProviderClient:\n \"\"\"Build a `ProviderClient` for `name` from its stored profile. Unknown → OpenAI default.\"\"\"\n descriptor = _BY_NAME.get(name) or _BY_NAME[\"openai\"]\n return descriptor.build(profile or {}, secrets)\n\n\ndef detect_provider(api_key: str) -> Optional[str]:\n \"\"\"Best-effort provider guess from an API key's shape, for the onboarding auto-detect.\n Returns a known provider name or None. Mirrors the GUI's client-side detection so both agree.\n \"\"\"\n key = (api_key or \"\").strip()\n if not key:\n return None\n if key.startswith(\"sk-ant-\"):\n return \"anthropic\"\n if key.startswith(\"AIza\"):\n return \"gemini\"\n if key.startswith((\"sk-\", \"sk_\")):\n return \"openai\"\n return None\n\n\ndef verify_provider_key(\n name: str,\n *,\n api_key: Optional[str] = None,\n base_url: Optional[str] = None,\n timeout: float = 10.0,\n) -> dict[str, Any]:\n \"\"\"Validate a provider's credentials with one cheap, read-only call (list models) — the same\n pattern connectors use to validate tokens. Transient: callers pass the key directly so a user\n can Test before saving. Never raises; returns {ok, error?}.\n \"\"\"\n import httpx\n\n d = _BY_NAME.get(name) or _BY_NAME[\"openai\"]\n key = (api_key or \"\").strip()\n try:\n if name == \"anthropic\":\n resp = httpx.get(\n \"https://api.anthropic.com/v1/models\",\n headers={\"x-api-key\": key, \"anthropic-version\": \"2023-06-01\"},\n timeout=timeout,\n )\n elif name == \"gemini\":\n resp = httpx.get(\n \"https://generativelanguage.googleapis.com/v1beta/models\",\n params={\"key\": key},\n timeout=timeout,\n )\n elif name == \"ollama\":\n base = _normalize_ollama_url(base_url)\n resp = httpx.get(base.rstrip(\"/\") + \"/models\", timeout=timeout)\n else: # openai + any OpenAI-compatible endpoint (Azure, OpenRouter, vendors, vLLM…)\n default_base = next(\n (f.default for f in d.fields if f.key == \"base_url\" and f.default), \"\"\n )\n base = (\n (base_url or \"\").strip().rstrip(\"/\")\n or default_base.rstrip(\"/\")\n or \"https://api.openai.com/v1\"\n )\n resp = httpx.get(\n base + \"/models\",\n headers={\"Authorization\": f\"Bearer {key}\"},\n timeout=timeout,\n )\n except Exception as exc: # DNS/connection/timeout — never let it bubble to a 500\n return {\n \"ok\": False,\n \"error\": f\"Couldn't reach {d.title} ({exc.__class__.__name__}).\",\n }\n\n if resp.status_code < 300:\n return {\"ok\": True}\n if resp.status_code in (401, 403):\n if name == \"ollama\":\n return {\"ok\": False, \"error\": \"Server rejected the request.\"}\n return {\"ok\": False, \"error\": \"Invalid API key.\"}\n if resp.status_code == 404 and name == \"ollama\":\n return {\n \"ok\": False,\n \"error\": \"Reached the server, but no OpenAI-compatible /v1 API there.\",\n }\n return {\"ok\": False, \"error\": f\"{d.title} returned HTTP {resp.status_code}.\"}\n"}}, "aisuite/providers/deepseek_provider.py": {"cb29165b00f719cceae6a82ed4621cbcb79aaaf7": {"t": 1785746717.4978888, "n": 2136, "h": "130ea33a8d10188e", "c": "\"\"\"Deepseek provider for the aisuite.\"\"\"\n\nimport os\nimport openai\nfrom aisuite.provider import Provider, LLMError\nfrom aisuite.providers.message_converter import OpenAICompliantMessageConverter\n\n\n# pylint: disable=too-few-public-methods\nclass DeepseekProvider(Provider):\n \"\"\"Provider for Deepseek.\"\"\"\n\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or \"\n \"set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"] = \"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for\n # OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n # Using OpenAICompliantMessageConverter since DeepSeek's response format is\n # the same as OpenAI's.\n self.transformer = OpenAICompliantMessageConverter()\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n try:\n response = self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs, # Pass any additional arguments to the OpenAI API\n )\n return self.transformer.convert_response(response.model_dump())\n except Exception as e:\n raise LLMError(f\"An error occurred: {e}\") from e\n"}, "f355c30a8d018d903f5193edbd862d6e84d56d36": {"t": 1785767233.9989219, "n": 2136, "h": "130ea33a8d10188e", "c": "\"\"\"Deepseek provider for the aisuite.\"\"\"\n\nimport os\nimport openai\nfrom aisuite.provider import Provider, LLMError\nfrom aisuite.providers.message_converter import OpenAICompliantMessageConverter\n\n\n# pylint: disable=too-few-public-methods\nclass DeepseekProvider(Provider):\n \"\"\"Provider for Deepseek.\"\"\"\n\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or \"\n \"set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"] = \"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for\n # OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n # Using OpenAICompliantMessageConverter since DeepSeek's response format is\n # the same as OpenAI's.\n self.transformer = OpenAICompliantMessageConverter()\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n try:\n response = self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs, # Pass any additional arguments to the OpenAI API\n )\n return self.transformer.convert_response(response.model_dump())\n except Exception as e:\n raise LLMError(f\"An error occurred: {e}\") from e\n"}, "f3a3061ea979d793ad602031857e6fb46778d634": {"t": 1785767235.3895192, "n": 1981, "h": "5bce1de036a3509f", "c": "import openai\nimport os\nfrom aisuite.provider import Provider, LLMError\nfrom aisuite.providers.message_converter import OpenAICompliantMessageConverter\n\n\nclass DeepseekProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"] = \"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n # Using OpenAICompliantMessageConverter since DeepSeek's response format is same as OpenAI's.\n self.transformer = OpenAICompliantMessageConverter()\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n try:\n response = self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n \n return self.transformer.convert_response(response.model_dump())\n except Exception as e:\n raise LLMError(f\"An error occurred: {e}\")\n"}, "51198e1edd459dfd49cea9900d95b24a1d4c49d2": {"t": 1785767237.2824094, "n": 1555, "h": "86a534908afa06fd", "c": "import openai\nimport os\nfrom aisuite.provider import Provider, LLMError\n\n\nclass DeepseekProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"] = \"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n response = self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n return response\n"}, "abe10594f56aba3d4092cd409082020aa0692fe7": {"t": 1785767238.5295942, "n": 1527, "h": "b95b7eeb55095970", "c": "import openai\nimport os\nfrom aisuite.provider import Provider, LLMError\n\n\nclass DeepseekProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"] = \"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n return self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n"}, "4e429e07f187d9b8bf8783bb13cff9051202e7ea": {"t": 1785767239.7803166, "n": 1525, "h": "e03e577acee26768", "c": "import openai\nimport os\nfrom aisuite.provider import Provider, LLMError\n\n\nclass DeepseekProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"]=\"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n return self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n"}, "f4f51d85897ffad55a3b5971a84bb4c22f5742ea": {"t": 1785767241.1482341, "n": 1515, "h": "b86416c660cd6fe3", "c": "import openai\nimport os\nfrom aisuite.provider import Provider\n\n\nclass DeepseekProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"]=\"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n return self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n"}, "6f114e19221f444f74e54c6ab177f30bd2a752f1": {"t": 1785767242.9708493, "n": 1513, "h": "0fa0761a450af556", "c": "import openai\nimport os\nfrom aisuite.provider import Provider\n\n\nclass OpenaiProvider(Provider):\n def __init__(self, **config):\n \"\"\"\n Initialize the DeepSeek provider with the given configuration.\n Pass the entire configuration dictionary to the OpenAI client constructor.\n \"\"\"\n # Ensure API key is provided either in config or via environment variable\n config.setdefault(\"api_key\", os.getenv(\"DEEPSEEK_API_KEY\"))\n if not config[\"api_key\"]:\n raise ValueError(\n \"DeepSeek API key is missing. Please provide it in the config or set the OPENAI_API_KEY environment variable.\"\n )\n config[\"base_url\"]=\"https://api.deepseek.com\"\n\n # NOTE: We could choose to remove above lines for api_key since OpenAI will automatically\n # infer certain values from the environment variables.\n # Eg: OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID. Except for OPEN_AI_BASE_URL which has to be the deepseek url\n\n # Pass the entire config to the OpenAI client constructor\n self.client = openai.OpenAI(**config)\n\n def chat_completions_create(self, model, messages, **kwargs):\n # Any exception raised by OpenAI will be returned to the caller.\n # Maybe we should catch them and raise a custom LLMError.\n return self.client.chat.completions.create(\n model=model,\n messages=messages,\n **kwargs # Pass any additional arguments to the OpenAI API\n )\n"}}}}