plugin-llm-openai — OpenAI LLM 服务
包名: @aalis/plugin-llm-openai
源码: packages/plugin-llm-openai/src/index.ts
概述
OpenAI 兼容接口的 LLM 提供者:为每个可用模型实现一个 LLMModel(@aalis/api-llm)并注册为 llm 服务条目(条目 id 为 <实例 id>/<modelId>),支持流式输出、工具调用和多模态图片输入。可对接任何兼容 OpenAI API 格式的服务。
插件声明
typescript
export default definePlugin({
name: '@aalis/plugin-llm-openai',
provides: [llm],
uses: {
config,
logger,
lifecycle,
provide,
events,
},
apply(caps) { /* 见源码 */ },
});每个模型登记时套上 metered:拿到用量的调用发 llm:usage(见 api-llm 的记账)。
配置
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
apiKey | string | — | API Key:OpenAI API 密钥(本地服务可留空)(secret)。baseUrl 的主机是 api.openai.com 时必填,留空则激活时报配置错误 |
baseUrl | string | 'https://api.openai.com/v1' | API 地址:API 端点完整前缀(含版本段,如 https://api.openai.com/v1);插件只在其后拼 /chat/completions 与 /models。可替换为任何兼容服务(如 Gemini 的 https://generativelanguage.googleapis.com/v1beta/openai)。 |
customModels | textarea | '' | 自定义模型:手动添加的模型名称(每行一个或逗号分隔)。用于补充自动发现列表中未出现的模型。与自动发现重复时会提示去重。 |
discoverModels | boolean | true | 自动发现模型:启动时请求 /models 发现可用模型,WebUI 可刷新模型列表。网关不提供 /models 时关闭:不发发现请求,只注册 customModels(此时必填),也不支持刷新。 |
modelCapabilities | textarea | '' | 单模型能力覆盖:按行指定某个模型的能力集。有该模型的表项时覆盖插件启发式推断,与 adapter 默认能力仍取并集。 格式:<modelId>: <cap1>,<cap2>,...,每行一条。如:gpt-4o: chat,tool_calling,vision,streaming 可用能力:chat / tool_calling / vision / streaming / thinking 等。 |
providerCapabilities | string | '' | 适配器默认能力(逗号分隔):为本适配器下所有模型额外补充的能力。最终某模型的能力 = 此处能力 ∪ 模型级别能力。例:chat,tool_calling,streaming |
timeout | number | 120 | 停顿超时(秒):多久收不到新的生成内容算超时(秒)。一直在输出不算超时;不流式的请求要在这段时间内收到整份回复。模型思考时不发出思考内容(如 OpenAI 官方的推理模型)或输入很长时,建议适当调大。0 = 不限制。 |
temperature | number | 0.7 | 温度:0-2,越高越随机 |
maxTokens | number | 4096 | 最大 Token:单次回复最大生成 token 数,须为正整数,否则实例转为出错 |
contextLength | number | 128000 | 上下文长度:模型上下文窗口大小 |
thinkingParam | select | 'reasoning_effort' | 思考档位的写法:能思考的模型(内置表里的 o 系列与 gpt-5 系列,gpt-5-chat 除外,或单模型能力覆盖里写了 thinking 的)按这种写法提供深度思考的档位。reasoning_effort:档位按模型族,发 reasoning_effort(OpenAI 官方与多数兼容端点);thinking:关、开,发 thinking: {type: enabled|disabled}(DeepSeek 风格的端点或中转)。请求指定了档位才发对应字段,没指定时不发、按端点自己的默认。端点不认所选字段时会拒收指定了档位的请求,这时换一种写法,或在单模型能力覆盖里去掉这个模型的 thinking。 |
特性
- SSE 流式:
chatStream()解析 SSE 事件流,累积 tool_calls delta - 思考档位: 能力里有
thinking的模型按thinkingParam声明档位——reasoning_effort写法按模型族:gpt-5.1 起(gpt-5.<n>)为关、低、中、高(none、low、medium、high,默认关),gpt-5 为最低、低、中、高(minimal起,默认中),o1-mini 与 o1-preview 不收这个字段、不声明档位,gpt-5-chat 是非推理模型、不声明档位,其余为低、中、高(默认中);thinking写法为关、开(off、on,默认开)。默认档写的是端点自己的默认。请求带了档位才发字段(reasoning_effort: <档位>,或thinking: {type: enabled|disabled}),没带时都不发;带了别的档位拒绝。拿不准的兼容端点在modelCapabilities里给思考模型写上或去掉thinking - 动态模型列表: 启动时请求
/models发现模型(停用或停机时中止),与customModels合并(重复项会告警)后逐个注册;发现失败(不可达、超时、非 2xx、响应不是 JSON 或不是模型列表)时记一条 warn(带 URL 与原因),只注册customModels。一个模型都没有(发现失败且未配置customModels,或已连接但列表为空)时实例转为出错,错误信息先写怎么修(检查apiKey、baseUrl与网络,或在customModels里写明要用的模型),再写原因。模型句柄上的refresh()会重新发现,并增删已注册的条目;发现失败时报错(消息带 URL 与原因),停用或停机时中止并报错,这两种情况都不增删条目 - 不提供
/models的网关: 关闭discoverModels。启动时不发发现请求、不记 warn,只注册customModels(此时必填,留空时实例转为出错并点名该字段),模型句柄不提供refresh(),WebUI 模型选择框旁的「刷新」会提示该 provider 不支持运行时刷新 - 超时:
timeout按停顿计,规则见 api-llm 的生成请求的超时。算作新内容的是content、思考(reasoning_content或reasoning,本插件不交出)与工具调用的名字和参数;超时报「LLM 请求超时:<timeout> 秒内没有收到新的生成内容,可在配置里调大 timeout」。对话请求经插件自己的连接池发出:没有 Node 自带 fetch 等响应头与读响应体各 300 秒的默认时限,也不走全局 dispatcher,经NODE_USE_ENV_PROXY或setGlobalDispatcher配的代理对它不起作用 - 错误信息: 对话请求失败时的错误信息会经 agent 发回会话,只写状态码与原因:非 2xx 时写状态码,401/403、402、404、429、5xx 各加一句提示(密钥无效或没有权限、余额不足或需要付费、模型或地址不对、请求过多或额度不足、上游服务故障),并附上游 JSON 里的说明(
error.message、error字符串或顶层message,折成一行后截断);取不到说明(如 HTML 错误页)时写「详情见日志」。超时、连不上、插件已停用或重载(停用或重载之后还拿着旧句柄发的请求)各一句;非流式请求的应答是 200 但不是 JSON 时写明。响应体与底层原因(如connect ECONNREFUSED <地址>)只记 warn 日志,响应体先把换行与连续空白折叠成一个空格,再截断到 500 个字符(按代理对安全截断)。模型发现失败的原因带响应体摘录(同样折叠与截断) - 地址与密钥校验: 不填
baseUrl时使用官方默认地址;显式填写的baseUrl若类型错误、解析不了、带查询串或片段(?或#之后的部分:插件在它后面拼路径,拼出来的地址是坏的),或带用户名或密码(user:pass@),读配置时实例转为出错、不发请求,也不会带着apiKey改发到默认地址。错误信息不带 URL;密钥填在apiKey。显式填写的apiKey类型错误时同样拒绝激活,避免丢失鉴权后继续请求;本地服务仍可不填密钥 - 兼容性: 修改
baseUrl可对接 Ollama、vLLM、LocalAI 等兼容服务——须写到完整前缀(如http://localhost:11434/v1)。注意 plugin-llm-ollama 自身的baseUrl语义不同:填服务器根地址(默认http://localhost:11434),由插件自行拼接/api/chat等路径 - 能力推断: 模型能力按内置家族表的模型名前缀推断,带
vision的有 gpt-4o、gpt-4.1、gpt-5、Gemini、通义千问视觉族(qwen-vl、qwen2.5-vl、qwen3-vl)与智谱视觉族(glm-4v、glm-4.1v、glm-4.5v),表外模型只推断为chat(另并上providerCapabilities声明的适配器默认能力)。vision决定 media 能否选它做识别模型,以及它做主模型时能不能亲眼看图(agent 据此填acceptsImages:当轮附件在 media 的vision.delivery=auto下直通原图,工具结果里的图交给它)。推断不准时用modelCapabilities逐模型覆盖;每行按最后一个冒号切分模型 id 与能力段,带冒号的 id(如经 Ollama/v1接入的qwen3:8b)照原样写即可