Files
Auto_Bangumi/docs/dev/plugins/points/llm-provider.md
Estrella Pan ca7fcdf058 chore(deps): httpx 全面迁移到 httpx2,SOCKS5 改用原生代理,升级 LLM SDK 大版本
- 依赖 httpx[socks] 换为 httpx2[socks]>=2.15,移除 httpx-socks / python-socks 及其 mypy 覆盖
- backend/src、ab_sdk、e2e 与单元测试统一使用 httpx2(异常类与 httpx 不通用)
- request_url 与 LLM 客户端工厂合并为 proxy_url(),SOCKS5 走 httpx2 原生代理(主机名由代理解析)
- 保留 #1104 过期连接池替换:httpcore2 2.15.1 的 start_tls 失败路径仍会泄漏隧道
- 日志同时压低 httpx2 与 httpx(google-genai、mcp 仍依赖旧 httpx)
- openai 3.35.1 / anthropic 1.15.0 / google-genai 2.31.0;结构化解析改用 chat.completions.parse
- ab_sdk 升到 0.6.0,客户端类型改为 httpx2.AsyncClient,同步插件文档
2026-10-20 10:56:32 +02:00

1.6 KiB
Raw Permalink Blame History

LLM 提供商(llm_provider)

增加一个 LLM 解析提供商。@provider(points.LLM_PROVIDER, id=...) 返回 ab_sdk.llm.LLMProviderAdapter 的子类,id 必须等于其 info.id。用户在 设置 → LLM → 提供商 里选择它。内置提供商的 id 不能被覆盖。

from ab_sdk import Plugin, points, provider
from ab_sdk.llm import AdapterContext, LLMProviderAdapter, ProviderInfo


class MyAdapter(LLMProviderAdapter):
    info = ProviderInfo(
        id="my-llm",
        display_name="My LLM",
        auth_kind="api_key",
        needs_base_url=True,
        default_model="my-model",
    )
    ...  # 实现 parse / list_models 等抽象方法


class MyPlugin(Plugin):
    @provider(points.LLM_PROVIDER, id="my-llm")
    def adapter(self):
        return MyAdapter

要点

  • ProviderInfo 驱动前端表单和提供商列表:auth_kind 为 api_key、oauth 或 device_code。
  • 适配器通过 AdapterContext 拿到模型名、密钥、base_url、超时和代理感知的 httpx2 客户端工厂,不读全局配置。
  • 工厂返回 httpx2.AsyncClient(SDK 0.6 起,此前为 httpx);捕获网络异常时用 httpx2.HTTPError 等,httpx 的异常类捕获不到它抛出的错误。
  • 订阅类提供商(oauth / device_code)实现认证流程钩子(AuthChallenge、TokenSet)。凭据失效且刷新失败时抛出 AuthExpiredError,AB 会熔断该提供商并发 llm_auth_failure 事件。
  • 现有的 plugin.json 格式 LLM 插件(llm-plugins 发布)继续可用;新插件使用 plugin.toml 与本扩展点。