@drama/llm
多厂商 LLM 网关。公共面(src/index.js)导出 createLLM、createStaticKeyProvider、LLMError 和 provider 注册表;协议差异全部圈在 src/providers/llm.<apiType>.js 子类,基类(src/base.js)零厂商分支。生产、诊断和验收都只调用真实 provider,不提供 fake provider 或 fetch 注入缝。
运行时会计链由 composition root 成组注入供应商成本、审计和积分结算端口。成功响应先严格构造 token 用量并记录价格快照与人民币 micros 成本,再按显式策略结算用户积分;运营探针可以三者全部省略,但不得只省略其中一部分。
OpenAI 兼容文本能力零文件接入
接入一个 OpenAI 兼容新厂商(DeepSeek 等)= 配置厂商主体、文本能力、key 和模型,零代码、零新文件:
INSERT INTO model_provider (code, display_name) VALUES ('deepseek', 'DeepSeek');
INSERT INTO model_provider_capability
(provider_id, code, capability, adapter, credential_source, base_url)
SELECT id, 'deepseek', 'text', 'openai', 'key_pool', 'https://api.deepseek.com/v1'
FROM model_provider WHERE code = 'deepseek';
INSERT INTO llm_key (vendor, api_key) VALUES ('llm:deepseek', '<key>');
INSERT INTO llm_model (provider_capability_id, model, pricing)
SELECT id, 'deepseek-chat', '<pricing-json>'
FROM model_provider_capability WHERE code = 'deepseek' AND capability = 'text';
装配从文本能力行构造实例:createLLM({ provider: row.adapter, vendor: row.name })。
adapter决定复用哪个 provider 子类(openai= Chat Completions 适配器)。base_url经lease.baseUrl承载厂商端点,永远优先于defaultBaseUrl()。vendor使 key 池按厂商身份隔离(同用openai适配器的两个厂商各命中自己的 key 池,详见任务 07 的vendor选项)。
仅当帧形态或多模态形态有厂商差异时才需新增 llm.<x>.js(如 gemini/volcengine);纯 OpenAI 兼容厂商只配置数据。
两套 OpenAI 适配器定位
同一 OpenAI 生态的两套协议收敛为两个适配器文件,经 model_provider_capability.adapter 二选一,不建平行体系:
| adapter | 文件 | 端点 | 用途 |
|---|---|---|---|
openai_responses |
providers/llm.openai_responses.js |
POST /responses |
OpenAI 厂商默认适配器(Responses API,store:false、独立 prompt_cache_key、缓存读写用量) |
openai |
providers/llm.openai.js |
POST /chat/completions |
OpenAI 兼容厂商(Moonshot / DeepSeek / Azure / 兼容网关) |
Visual Game 持续 Agent 通过独立 prompt_cache_key 固定缓存身份。模型参数提供
prompt_cache_options: { mode: 'implicit' | 'explicit', ttl?: '30m' } 时,static 消息同时发送
prompt_cache_breakpoint;未提供时不发送这两个公开缓存控制字段。Responses usage 统一构造
cached_tokens 和 cache_write_tokens,供应商未报告的可选明细在第三方响应入口构造为 0。
视频支持面
视频落地/拒绝由基类 supportsVideo() 能力钩子驱动(base.js 的 request() 单点护栏),基类零厂商分支:
| provider | 视频 |
|---|---|
gemini |
支持(inline_data base64 / file_data url) |
volcengine |
支持(video_url 块) |
openai / openai_responses / anthropic / moonshot / azure_foundry |
收到 videos 抛 LLMError{ reason:'badRequest', retryable:false } |
扩展视频厂商 = 在子类覆写 supportsVideo() 返回 true,并在 chat/_toOpenAIMessages 落该厂商的视频块。