# 聊天路由与模型状态 [English](../en/chat-routing.md) · [返回 README](../../../README.md) ## 插件怎么和面板通信 插件和面板之间有两条通道。 - 控制面:列模型、启停、查状态、就绪探测,走 llamapad 的 REST API,请求头带 `Authorization: Bearer lp_xxx`。 - 数据面:`/v1/chat/completions` 的 SSE 流式输出,有两种模式: - `proxy`(默认):经过面板反代。dsh 和 GPU 服务器不在同一个网络时用这个,llama.cpp 的端口不用对外暴露。 - `direct`:直连 llama.cpp,适合同机部署、想省掉一跳延迟的情况。代价是用不了思考强度,见[配置参考](configuration.md#思考强度reasoning_effort)。 插件不修改 llamapad 的任何东西,只调用它公开的接口。 ## 多个模型同时运行 新版面板允许同时跑多个模型(面板的 `feature/multi-model` 分支,目前还没合并进主线,本插件提前做了适配)。在这种面板上: - `runtime/status` 里的 `running` 表示默认模型,也就是不带模型名的请求会发给谁; - 实际在跑的全部模型列在 `models[]` 里。 老面板没有 `models[]` 字段,插件把唯一在跑的那个模型当作默认模型,行为和以前一样。 ## chatBehavior:选模型会不会触发启停 在 dsh 里选中一个模型发消息时,插件怎么处理由 `chatBehavior` 决定。 | 档位 | 目标模型在跑 | 目标模型没在跑 | 适合 | |---|---|---|---| | `strict`(默认) | 直接发送 | 报错,提示去面板启动 | 多人共用 GPU、多会话并行 | | `passthrough` | 直接发送 | 改发给面板的默认模型;没有默认模型就报错 | 只想连上当前那个服务 | | `auto-switch` | 直接发送 | 自动启动它,等就绪后再发送 | 一个人独占 GPU | 补充几点: - `strict` 下聊天路径不会调用 start。正在输出的对话不会因为别人切模型被打断。目标模型只要在运行集合里就能用,不要求是默认模型。 - `auto-switch` 只保证目标模型在跑,不会为了它停掉别的模型。插件只负责连接和调度,不替你管理服务端的资源。显存不够时启动会失败,报错信息里会列出还占着显存的模型,你需要去面板手动停掉。 - 启动前默认会先让服务端把正在推理的请求处理完(`drainOnSwitch`,最多等 `drainTimeoutMs`)。 - 插件内部有一把串行锁,多个请求同时要启动同一个模型时会合并成一次,不会反复启停。 - 等待模型就绪期间不会往对话里插提示文字,那样会混进历史上下文。原因见[调研文档](../../research/2026-08-24-dsh-plugin-research.md) §5。 ## 切换默认模型 目标模型必须已经在跑。有两个入口: - 管理工具 `llamapad_set_default_model`,见[管理工具](tools.md) - 设置卡片运行列表里的「设为默认」按钮,见[设置卡片与监控页](web-ui.md) 老面板不支持这个操作,插件会直接提示需要多模型版本的面板。 ## 模型选择器上的标记 - `▶︎` 表示模型正在运行。这里特意加了 U+FE0E 变体选择符,免得某些系统把它渲染成彩色 emoji。 - `★` 表示默认模型,说明文字末尾还会写上「默认(不指定模型的请求发给它)」。两个标记可以同时出现,比如 `▶︎ ★ qwen3-8b`。 - 模型配置了但文件缺失(`missing-file` / `missing-mmproj`)时,说明文字后面会附一句提示。这类模型启动时一定会返回 422,提前标出来可以少踩一次坑。 打开 `hideStoppedModels` 后,选择器只显示运行中的模型。`auto-switch` 档会忽略这个开关并打一条警告,因为这一档靠选中没启动的模型来触发启动,隐藏掉就没法用了。 ## 状态怎么保持最新 插件在 dsh 后端常驻一条 SSE 连接,订阅面板的 `/api/v1/events/stream`。收到 `model.*` 事件(启动、停止、异常退出)后,插件马上查一次运行状态。只有在跑的模型真的变了,才通知 dsh 重新拉取模型目录。浏览器那边不轮询。 两种兜底: - SSE 连续 3 次建连失败,就退回定时轮询,面板恢复后自动切回事件模式。 - 连接断了但没有报错时,由看门狗按 `statusRefreshMs` 的节拍检查最新事件 id,发现落后就重连补齐。 `statusRefreshMs: 0` 表示完全关闭,SSE 也不连。关掉之后选择器上的标记会一直停在插件启动时的状态。