DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

cqnxnzg /

cqnxnzg/dsh-llm-openai-compatible

Verified

MIT License Copyright (c) 2026 cqnxnzg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell cop

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@20776fdb

dsh-llm-openai-compatible(万能插头)

让 DeepSeek Harness 接上任意 OpenAI 兼容端点:本地 vLLM / LM Studio / llama.cpp 服务器、Ollama 的兼容层、或任何远程网关(OpenRouter、Together、Moonshot 等)。装完 + 配好端点就能跑——不需要装 Ollama,也不需要改 dsh 核心。

设计目标:这个插件自己就是一个「万能插头」——一个 provider 路由(openai-compatible),任何说 OpenAI Chat Completions 协议的服务都能插上来。

特性

  • 任意 OpenAI 兼容端点:baseURL 配 http://127.0.0.1:8000 或 http://127.0.0.1:8000/v1 都行(自动归一化到 /v1)。
  • API key 可选:本地服务通常不需要鉴权——没配 key 时请求匿名发出(本地端点忽略多余 Bearer 头);远程网关必须配 key,否则 401。
  • 模型目录:models 数组声明端点实际提供的模型(id / contextWindow / maxTokens / vision / thinking / defaultEffort)。
  • Web 配置:Settings → Plugins → llm-openai-compatible,通用表单即可改端点、key、模型目录、重试策略,保存即时生效。
  • 模型发现:discoverModels() 读 GET <base>/v1/models,返回端点真实提供的模型 id 列表。
  • 免 allowlist 安装:仓库提交构建产物 lib/(无 prepare 脚本),GitHub 安装不需要 pnpm 的 build-script 白名单。

安装

要求 DeepSeek Harness 0.1.0-rc.6+。

# 从 GitHub 安装(推荐,免本地构建)
dsh plugin --profile web add github:cqnxnzg/dsh-llm-openai-compatible

# 本地开发安装(<仓库路径> 替换为克隆下来的插件目录;先 pnpm run build)
dsh plugin --profile web add <仓库路径>/dsh-llm-openai-compatible

dsh web

GitHub 安装无需 build-script allowlist:仓库提交了构建产物 lib/(无 prepare 脚本),装完即可用。本地开发时改源码后记得 pnpm run build 再重装。

配置

最小配置(本地 vLLM 等)

默认 baseURL = http://127.0.0.1:8000/v1,默认模型目录里有几个常见本地模型 id。打开 Settings → Plugins → llm-openai-compatible,把 models[].id 改成你本地服务实际提供的模型 id(见下文「UNKNOWN_MODEL 怎么消除」),保存即可在模型选择器里选中聊天。

配置字段(全部可选)

字段 默认 说明
apiKeyEnv OPENAI_API_KEY 凭据引用(环境变量名);未配置/为空 → 匿名请求(本地端点可用)
baseURL http://127.0.0.1:8000/v1 OpenAI 兼容端点;自动归一化到 /v1
models 4 个示例模型 端点实际服务的模型目录;未列出则请求报 UNKNOWN_MODEL
maxTokens — 全局默认输出上限;模型行未声明时兜底
defaultContextWindow 131072 模型未声明 contextWindow 时的上下文容量
streamIdleTimeoutMs 300000 流式读取空闲超时
retryPolicy 正常默认 重试策略(见下)

models[].* 字段语义:

字段 说明
id 端点接受的模型 id(必须与端点实际服务的一致,否则 UNKNOWN_MODEL)
name 选择器显示名;省略用 id
description 选择器里的补充说明(可选)
contextWindow 该模型上下文容量(token)
maxTokens 该模型专属输出上限,优先于全局 maxTokens;请求级 maxTokens 又优先于它
vision true = 接受图片输入(请求带图时输入模态含 image)
thinking true = 支持原生思考;选择器可调 thinking 等级(off/low/medium/high/max)
defaultEffort 聊天选择器的默认思考等级;需 thinking: true 且等级在支持集合内才生效
tools 遗留能力标志,运行时忽略,仍被解码

retryPolicy 可配置值(省略 = 正常默认:最多重试 2 次,重试码 EMPTY_RESPONSE/RATE_LIMIT/SERVER/TIMEOUT/TRANSPORT,退避 initialDelayMs: 500 / maxDelayMs: 10000 / jitterRatio: 0.1):

retryPolicy:
  mode: normal            # normal | always
  maxRetries: 3           # normal 模式:最大重试次数
  retryableCodes: [RATE_LIMIT, SERVER, TIMEOUT, TRANSPORT]  # normal 模式:可重试错误码
  backoff:
    initialDelayMs: 500
    maxDelayMs: 10000
    jitterRatio: 0.1
# mode: always  = 无条件重试(只有 backoff 字段),一般用于本地服务

常见本地端点

服务 baseURL 备注
vLLM http://127.0.0.1:8000/v1 默认值;--served-model-name 指定的名字才是请求 id
LM Studio http://127.0.0.1:1234/v1 —
llama.cpp server http://127.0.0.1:8080/v1 —
Ollama(兼容层) http://127.0.0.1:11434/v1 Ollama 原生 API 不是 OpenAI 协议;必须走它的 /v1 兼容层,模型 id 常带 tag,如 qwen2.5:7b
OpenRouter https://openrouter.ai/api/v1 网关,必须配 apiKeyEnv,否则 401
Together https://api.together.xyz/v1 网关,必须配 apiKeyEnv,否则 401
其他远程网关 https://.../v1 网关通常需要 key;见故障排查

接 DeepSeek 官方 API 完整示例

DeepSeek 官方端点本身就是 OpenAI 兼容的。在 Settings → Plugins → llm-openai-compatible(或 settings 文档的 llm-openai-compatible 节)里:

llm-openai-compatible:
  apiKeyEnv: DEEPSEEK_API_KEY        # 环境变量里放你的 DeepSeek API key
  baseURL: https://api.deepseek.com  # 自动路由到 /v1,不用手写 /v1
  models:
    - id: deepseek-chat              # DeepSeek-V3,通用对话
      name: DeepSeek Chat
      contextWindow: 65536
      maxTokens: 8192
      tools: true
    - id: deepseek-reasoner          # DeepSeek-R1,推理模型,需要 thinking
      name: DeepSeek Reasoner
      contextWindow: 65536
      maxTokens: 8192
      thinking: true

要点:

  • baseURL: https://api.deepseek.com 即可——插件会自动补 /v1(等价于写 https://api.deepseek.com/v1)。
  • deepseek-reasoner 是推理模型,目录行要标 thinking: true,这样选择器才能正确展示思考等级。
  • 环境变量 DEEPSEEK_API_KEY 由 dsh 的凭据缝读取(apiKeyEnv 指的就是环境变量名);配好 key 后请求带 Bearer 鉴权,不会 401。

无真实模型也能测(装完后的第一课)

node scripts/mock-server.mjs   # 起一个 OpenAI 兼容 mock(GET /v1/models + POST /v1/chat/completions)
pnpm run smoke                 # 用构建产物跑一次 adapter 全链路,打印模型列表 + 流式回复
pnpm run verify                # 系统性自验证:52 项断言(纯函数 / schema / adapter / discovery)

smoke 打印 SMOKE OK、verify 打印 VERIFY OK 且退出码 0 = 万能插头端到端打通。

真实 dsh profile 端到端验证

已用一个独立 profile(plugtest)验证过完整链路:dsh-base + dsh-headless + 本插件,patch 层把 agent-default-model 指向 openai-compatible/gpt-oss-120b、插件 baseURL 指向本地 mock, 然后一次 headless 任务直接拿到 mock 的回复:

dsh --profile plugtest "你好,请用一句话自我介绍"
# [mock:gpt-oss-120b] 你好,万能插头已接通!Hello from the OpenAI-compatible mock. auth=Bearer no-key-local

验证要点:插件在真实 profile 中加载、provider/adapter/discovery 注册、agent loop 走通、 settings 指向 profile 专属文件(不触碰全局 ~/.dsh/settings.yaml)。

UNKNOWN_MODEL 怎么消除

UNKNOWN_MODEL 表示请求的模型 id 不在插件的 models 目录里。按下面三步解决:

  1. 问端点要真实 id:

    curl http://127.0.0.1:8000/v1/models
    # {"object":"list","data":[{"id":"Qwen/Qwen2.5-7B-Instruct",...}, ...]}
    

    把 data[].id 原样抄进 models[].id(插件也提供 discoverModels() 做这件事,Web 配置的「fetch models」动作可一键导入)。

  2. vLLM 特殊:启动参数 --served-model-name 决定请求 id,可能与你下载的模型名不同(比如下载的是 Qwen2.5-7B-Instruct,服务名却是 qwen-7b)。以 curl /v1/models 返回的为准。

  3. Ollama 特殊:兼容层返回的 id 常带 tag(如 qwen2.5:7b),照抄,别去掉 :7b。

故障排查

症状 原因与解法
UNKNOWN_MODEL 模型 id 不在 models 目录;按上文「UNKNOWN_MODEL 怎么消除」抄真实 id
401 Unauthorized 端点需要 key:apiKeyEnv 配了没?环境变量值对吗?本地端点不需要 key 时把 key 清空(匿名请求)
404 / 连不上 baseURL 写成了完整路径(如 .../v1/chat/completions)——只要 base,插件自动补 /v1;或服务没起 / 端口不对
/v1 写两遍 baseURL 写 http://host:8000/v1 或 http://host:8000 都行,不要写 http://host:8000/v1/v1
模型选择器里没有我的模型 models[].id 与端点返回不一致;或保存后没等配置生效(保存即生效,重开选择器刷新)
匿名请求被本地端点拒绝 个别本地服务校验 Bearer 头;给它配一个任意 key(apiKeyEnv 指向一个假值)试试

诊断命令(从插件目录跑):

curl http://127.0.0.1:8000/v1/models            # 端点到底有哪些模型 id
node scripts/mock-server.mjs && pnpm run smoke  # 插件链路是否自洽(不依赖真实端点)

工作原理

  • 插件入口 apply(ctx, config):ctx.llm.registerConfigurableProviders() + ctx.llm.registerAdapter() + ctx.llm.registerModelDiscovery() + installSettingsSection()(参考 dsh-llm-ollama 的注册机制)。
  • 聊天走 pi-ai 的 OpenAI Chat Completions:createProvider({ api: openAICompletionsApi(), baseUrl, auth, models }),每次请求通过 harness 的凭据缝解析 key。
  • 连接事实(endpoint / key / 模型目录)每次操作重新解析,Settings 里改了立即生效,不用重启。

开发

pnpm install
pnpm run build    # tsc(lib/types/*.d.ts)+ tsdown(lib/index.js)
pnpm run smoke

构建产物 lib/ 与声明文件 lib/types/**/*.d.ts 提交进 git(.gitignore 只排除 tsc 中间产物),因此 GitHub 安装无需 build-script allowlist——这是与 dsh-hello-tool(依赖 prepare 脚本)不同的安装策略。

路线图

  • Host 端最小可用版(聊天 + 配置 + 发现)
  • Settings → Providers 专属卡片(fetch models 一键导入、模型行内编辑)
  • 多 provider 路由(同时挂 vLLM + LM Studio)
  • 发布到 npm / GitHub Releases

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 20776fdba46f

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout