全部插件

DSH / BUNDLE / CLIENT-UI

dsh-plugin-local-model

v0.5.3DZQJOKER / dsh-plugin-local-model9068cf25de

可安装组合包UI 与客户端插件社区 · Topic 自动分析Web UI

概览

dsh-plugin-local-model

DeepSeek Harness 本地模型插件:设置里独立的「本地模型」页,首条对话自动拉起 llama.cpp,空闲 5 分钟自动卸载释放资源。

README / ZH

插件文档

目录摘要

DeepSeek Harness 本地模型插件:设置里独立的「本地模型」页,首条对话自动拉起 llama.cpp,空闲 5 分钟自动卸载释放资源。

dsh.pub 核对固定版本的组合包契约、运行时事实与分发语义;完整 README 请查看源仓库。

在 GitHub 阅读完整 README

LIMITATIONS

已知限制

dsh 目前处于开发者预览期,接口仍在变动,因此**所有宿主集成点都做了显式降级,宁可少做也不报错**: - 本插件 `inject` 为空:`llm` / `tools` / `commands` / `timer` 全部通过 `ctx.get()` 读取, 缺失或接口对不上时只跳过对应增强,**模型加载与空闲卸载这条主线始终可用**。 - `llmBridge` 会依次探测 `registerProvider / upsertProvider / registerRoute / addRoute / setRoute`, 全都不匹配时打印可直接粘贴的 `settings.yaml` 片段(第 5 节),而不是失败。 - `/local-model` 命令同时挂了 `execute` 和 `run` 两种入口名,以适配不同版本的 commands 服务。 - `src/commands.ts` 与 `/local-model status` 的输出格式可能随宿主调整而调整 —— 它们只是便利功能, 真实状态以 `GET http://127.0.0.1:18080/local-model/status` 为准。 - `types/dsh-ambient.d.ts` 是**离线编译用**的环境声明(只覆盖本插件用到的接口)。 在 dsh 仓库内开发时以主仓库的真实类型为准;若出现重复声明告警,把它从 `tsconfig.json` 的 `include` 里去掉即可。 - 未做:多模型同时常驻(严格一次一个,符合"释放资源"的目标)、图像输入透传的端到端验证、 Windows 上 llama-server 的优雅退出(llama.cpp 无状态可刷,直接结束进程树)。 ### 浏览器半侧是复刻的构建,不是官方预设 dsh 官方明确说明产出 `dsh.client` bundle 的 `clientBundle` 预设**不在已发布的包里**, 仓库之外的插件必须自己复刻。本项目的复刻落在 `scripts/build-client.mjs`:esbuild 打成 CJS (`react` / `react/jsx-runtime` 全部 external,由宿主提供),再手工套上 `window.__ModuleLoader__.load({ id, factory })` 外壳;形状是拿本机三个**已经在生效**的 `dsh.client` 包的产物逐字节对照出来的,并由 `npm run test:client` 用假 loader 真跑一遍守住。 升级 dsh 后如果设置页不出现,先跑这两个脚本,再检查 `dsh.client.inject` 里的客户端包名是否仍然存在。 面板的数据面是**自建的同源 HTTP 桥**而不是 dsh 的 settings 命名空间(原因见第 4 节), 因此设置写在插件自己的 `<DSH_HOME>/local-model/state/config.json` 里。这是刻意的取舍: 它不依赖宿主内部接口的版本,代价是这些设置不出现在 `settings.yaml` 中,也就不能跟着 dsh 的凭据/同步机制走。桥只服务回环来源 —— 通过局域网访问 dsh 时面板不可用。 界面文案目前是中文硬编码(只额外注册了中英两份分区标题词条)。 ### 本包的 manifest 是按实机对照确认的 `dsh.bundle` 与 `dsh.client` 的形状不是照文档猜的,是拿本机几个**已经在生效**的第三方插件 逐个字段对出来的(`dshmarket`、`@linxin666/dsh-web-all`、`dsh-better-sidebar`): ```json "dsh": { "bundle": { "patch": "./cordis.patch.yml" }, "client": { "inject": ["@deepseek-ai/dsh-client-locale", "@deepseek-ai/dsh-client-ui-settings"], "platform": "web" } } ``` `engines.dsh` 是给市场/网站读的版本闸门(市场会把 `engines.dsh` 与 `@deepseek-ai/*` 的 peer 范围一起收进兼容性卡片)。写它有个坑:**不带预发布分支的范围会静默匹配不到 harness 的 `-rc.x` 构建** —— node-semver 只在范围里某个比较符与该版本的 `major.minor.patch` 元组完全一致、且自身带预发布标签时才放行预发布版本。所以这里用显式的 `||` 分支: ```json "engines": { "dsh": "^0.1.0-rc.1 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-0" } ``` harness 出一个新的 minor 预发布(例如 `0.1.6-rc.1`)时需要补一个分支,这是这类声明 固有的维护成本。`peerDependencies` 同一处理:官方 `@deepseek-ai/*` 一律写进 `peerDependencies`(而不是 `dependencies`),并全部标 `optional`。原来写的 `"*"` 看着最宽, 实际受同一条 semver 规则影响**匹配不到任何 `-rc.x`**。 `cordis.patch.yml` 里的 loader entry id 带作者前缀(`dzqjoker-local-model`),不用裸的 `local-model`:cordis 拒绝加载含重复 entry id 的插件树,而插件市场一旦发现新装插件的 id 与已加载的相撞,会直接把该插件卸载(否则下次启动整个 profile 都起不来)。 `exports` 只声明了 `.` / `./client` / `./cordis.patch.yml` / `./package.json` 四个入口, 与上述包的风格保持一致。 `repository` 字段必须指回本仓库 —— 插件市场用它把 npm 包与列表条目关联起来。 本包不再有 `private` 字段:它是要被公开安装的插件。