- Inicio
- Plugins
- Integraciones y acceso remoto
- agent-manager
agent-manager
let-mi-think/agent-manager
Crea y configura presets de Agent desde una sola sección: prompt de persona, lista marcada de entradas de la base de conocimiento que se inserta en el prompt de sistema, interruptores individuales para cuatro herramientas de conocimiento, restricción de conexiones MCP por Agent e importación por lotes.
Instalar
dsh plugin --profile web add github:let-mi-think/agent-managerREADME
dsh-agent-manager
多 Agent 管理与配置插件(DeepSeek Harness)。与 dsh-eli-mode 并存,不改动它的任何文件。
安装
dsh plugin --profile web add dsh-agent-manager
装完重启 dsh web,设置里会出现 Agent 管理 分区。
- 宿主要求:
dsh0.1.0-rc.7(见package.json的dsh.engines.dsh);Node^22.19.0 || ^24.0.0。 - 知识库是可选依赖:知识库清单 / 导入 / 重建索引这组功能复用
dsh-eli-mode的eliKb服务。 没装 eli-mode 时它们显示为禁用态,其余配置照常可用。 - 客户端产物随包分发(
lib/client.js已提交),安装时不需要构建。
它做什么
- 在 DSH 设置区新增一个「Agent 管理」分区:先选 Agent,再配置它(比 Eli Mode 的单体配置多出「多 Agent 选择」这一步)。
- 在官方「Agent 预设」卡片上叠加一个「编辑」按钮,点开直接进入该 Agent 的配置。
- 每个 Agent 可配置:人格 prompt、知识库注入 prompt 模板、可勾选的知识库条目清单(勾选后把条目清单注入提示词,正文由
kb_read按需取)、四个知识库工具的独立开关、可用哪些 MCP 连接。 - 注入清单的每行是
- <条目路径> — <标题>(与 eli-mode 生成的目录页同格式):标题让 Agent 光看清单就知道该读哪一篇,中文文件名下标题自然就是中文。 - 新建 Agent:选一个现成预设作蓝本,插件复制它的目录并改写组合文件,新 Agent 立刻出现在预设选择器里(新会话生效)。
- 导入知识库:填一个目录路径 → 扫描预览 → 整批导入(用于初始化 / 迁移一批文档),顺带补上知识库本身没有的「重建索引」入口。
三个平面
| 平面 | 文件 | 挂载方式 |
|---|---|---|
| host | lib/index.js | 本插件 cordis.patch.yml 的 insert |
| preset | lib/preset.js | 每个生成的 Agent 预设在自己的 agent.cordis.yml 里按 id 挂载 |
| 浏览器 | lib/client.js | package.json 的 dsh.client |
preset 平面由预设自己挂载,是为了让它天然绑定到「自己服务哪个 Agent」——挂载行里带 config.presetId。
配置存哪
- 配置数据:
~/.dsh/settings.yaml的agent-manager段,形状agents: { <presetId>: { ... } }。由插件注册的设置命名空间读写,不写进预设的组合文本。 - 归属标记:新建的预设目录里写一个侧车文件
.agent-manager.json,记录managedBy/blueprintId/createdAt。删除只允许删带这个标记、且位于~/.dsh/.agent-presets/之下的目录,避免误删eli-mode、wechat等既有预设。
知识库
复用 dsh-eli-mode 的 eliKb 服务读取 ~/.dsh/eli-knowledge(同一份 wiki),不重复实现一套。因此:dsh-eli-mode 被停用或升级导致 eliKb 不可用时,知识库清单会显示禁用态,其余配置不受影响。
导入(初始化一批文档)
「Agent 管理」头部的「导入知识库」:填源目录(绝对路径)→ 扫描 出预览(+ 新增 / = 已存在、并列出被跳过的文件及原因)→ 导入 N 项。
- 目录结构原样变成条目路径,可再套一个「落点前缀」,例如把
C:\...\docs导成tripartite/...。 - 只认
.md/.markdown;跳过index.md(各级目录页)、隐藏目录、node_modules等;默认跳过已存在的同名条目(可勾选覆盖)。 - 默认补标题行:源文件首行不是
# 标题时,导入时会在最前面补一行# <文件名>(原内容一行不删)。原因见下。 - 只复制(或补标题行后写入)文件,源目录不动;导入后插件会自动调一次
eliKb.regenerateAllIndexes()。
为什么必须补标题行(eli-kb 会丢首行)
kb.js 的 _readRaw 是这么取正文的:
let title = norm.split('/').pop()
if (lines[0].startsWith('# ')) title = lines[0].slice(2).trim() // 标题
const body = lines.slice(1).join('\n') // ← 首行被丢掉
return { id, title, content: '# ' + title + '\n\n' + body }
首行永远被丢弃:是 # 标题 时"丢得正好"(标题另外存了),不是时那一行正文就永久读不到 —— Agents 读不到、知识库网页看不到、search 也搜不到(search 基于同一份裁过的 content)。上游自己因此约定「首行即标题」(write() 强制写 # title,自带种子 wiki 的文件首行全是 # 标题)。
已有条目如果踩了这个坑(例如手拷进 wiki/ 的文件),用脚本就地补,不必删了重导(在包目录里执行):
node scripts/fix-title-lines.mjs # 预览(不写文件)
node scripts/fix-title-lines.mjs --apply # 执行:先备份,再补行,最后重建索引
# 个别条目的标题取自自身小标题(如 `# 1. 概述`)时,可用文件名重写:
node scripts/fix-title-lines.mjs --apply --force=6
备份落在 ~/.dsh/eli-knowledge/.titleline-backup-<时间戳>/(在 wiki/ 之外,不会被当成条目)。
为什么必须由插件来重建索引
会话清单读的是知识库根索引 ~/.dsh/eli-knowledge/index.md,而它只在 eli-kb 自己 write() / remove() / init()(且根索引不存在)时重建,知识库没有任何路由或按钮能手动触发。所以直接往 wiki/ 拷文件会出现「文件在、list() 看得见、Agent 却完全不知道」的哑谜。本插件为此提供两处入口:
# 面板内:导入知识库 → 仅重建索引
# 命令行(DSH 没跑起来时,在包目录里执行):
node scripts/reindex-kb.mjs
# 调 prompt 模板/清单格式时,先看看 Agent 到底会收到什么:
node scripts/preview-injection.mjs [presetId]
三个脚本都用 scripts/eli-kb.mjs 定位 dsh-eli-mode 的 lib/kb.js:先看环境变量 ELI_KB_MODULE,再按 Node 解析规则从当前目录找 dsh-eli-mode,最后试仓库内 vendored 快照。找不到时会直接告诉你该装什么或该设哪个环境变量。
中文条目名需要 dsh-eli-mode 的一个补丁
中文 / 下划线 / 空格命名的条目能否被读取,取决于 dsh-eli-mode 的 lib/kb.js 里 normalizeId 的字符集限制:
- 上游原版只接受
[a-z0-9-]段名 → 这类条目「能列出但读不到」(list()/tree()/search()不走校验,read()/write()/remove()/双链解析才走),表现为知识库网页点不开、kb_read返回空、kb_write还会把中文标题 slugify 成entry-xxxx。 - 补丁后只校验「段非空且不是
./..」并拒绝 NUL:字符集任意,仍拒绝路径穿越,id 永远落在wiki/之内。
补丁的判定只影响读取。要放中文条目,请让 eli-mode 使用打了补丁的版本(差异就是 kb.js 里 normalizeId 那一个函数)。
MCP 连接(按 Agent 收窄)
- 数据来源是工具注册表,不是连接器的存储或它的 status 接口:连接器把每个 server 的工具注册成全局工具
mcp__<serverName>__<toolName>,所以「装了哪些、有哪些工具」以ctx.tools.schemas()为准。实测连接器自己的status接口报 0 个连接时,工具表里仍有 1 个真实连接(5 个工具)——按 status 做会误判成「没有 MCP」。 - 怎么收窄:预设平面的 ctx 就是「该 Agent 的 scope」(DSH 为每个预设
createScope(selfCtx, { agentPreset: <id> })),因此在 preset 平面调用官方ctx.tools.restrict({ deny }),未勾选连接的工具会同时从 schema、lookup 与 dispatch 中消失。这与 MCP 连接器收窄工作区用的是同一套机制。 - 默认不限制:
mcpRestrict默认 false = 沿用「全部已连接的 MCP 都能用」,避免升级后静默砍功能。开启后才按mcpServers精确放行(勾选为空 = 全禁)。 - 会跟随工具表变化重算:订阅
tools/registered,连接增删后按新工具表重新计算(否则重连之后仍被旧限制挡住)。重算前会先撤销自己的限制再读工具表,避免「读到被自己遮蔽后的子集、越算越少」。 - 失败即降级:
restrict()若抛错(例如名字刚好失效、或该 scope 不允许限制),只记一条 warn 并保持不限制——不会让整个预设挂载失败。 - 一个命名边界:连接器对超长/含特殊字符的工具名会截断并加 12 位哈希后缀,那种名字解析不出 serverName,本插件会把整条名字当成一个独立分组列出来(可选可放行),不会静默丢弃或静默禁用。
已知限制
- 卡片上的「编辑」按钮是 DOM 注入:DSH 官方没有预设卡片级插槽(只有
settings.section这类通用插槽)。选择器只用本地名后缀匹配([class*="_card"]等),官方卡片结构变化时按钮会自动不注入并记一条 warn——独立分区仍然可用,功能不丢。 - 工具开关是执行期拦截:预设组合按 preset 只挂载一次,注册期裁剪要重启才生效,所以四个工具一次性全部注册,在
execute里按开关拒绝并返回说明。代价是禁用中的工具仍会出现在工具清单里。 - 新建 Agent 需要直接写
~/.dsh/.agent-presets/<id>/,绕过了官方AgentPresets服务「只允许整目录复制」的授权限制;因此改写只做按行文本修改 + YAML 校验 + 失败回滚,尽量保留蓝本里的注释。 - 导入是「复制 + 重建索引」,不做去重合并:同一条目改了别处不会自动同步;想更新就开「覆盖」重新导一次。
- 用
eli-kb自己的remove()删条目时,若该目录已生成了index.md(导入必然生成),空目录不会被自底向上清掉,会留一个只有index.md的空壳目录;条目列表不受影响(index.md不算条目),需要时手动删目录。
开发
npm install # 需要 devDependencies(tsdown / typescript / @types/*)
npm run build # 产出 lib/client.js(已随仓库提交,运行时无需构建)
npm run typecheck
npm test # node --test tests/*.test.mjs(不依赖 dsh-eli-mode)
host 半与 preset 半是免构建的 lib/*.js;只有浏览器半需要 tsdown 打包,再由 scripts/wrap-client.ts
包成 DSH 的 window.__ModuleLoader__.load 形状。npm publish 前 prepack 会自动跑一次构建。
需要真实 eliKb 实例的那部分测试(含中文 id 补丁与索引重建的验证)在开发用的单体仓库里维护,不随包发布。
上架(awesome-dsh-plugin / dsh-market)
插件市场里的列表来自精选列表仓库 awesome-dsh-plugin, 收录方式是往那边提 PR 新增一个条目文件(不是往 dsh-market 提):
- fork 该仓库,把本仓库的
contrib/let-mi-think__agent-manager.yml复制成data/plugins/let-mi-think__agent-manager.yml(文件名必须与仓库一致); - PR 前确认本仓库已声明
dsh.bundle且根目录有cordis.patch.yml(两个都已具备); - 给 GitHub 仓库加
dsh-plugintopic,并确保仓库创建已满 1 天(CI 会检查); - 提 PR(一个 PR 最多 3 条,且只改自己那一条)。合并后站点与市场的 README 会自动重建,不要手工编辑那边的 README。
npm 包不是收录的必要条件,但发了才能显示下载量:npm publish 后映射会被自动采集
(条目里不要写 npm: 键,写了会被校验拒绝)。本仓库的 repository 已指向自己,
prepack 会在发布前自动跑一次构建,lib/ 也已随仓库提交,因此从 npm 安装无需构建。
可选增强:在仓库根放 screenshots.json(1–8 张图,路径相对该文件、不能跳出仓库)
可以让市场显示应用商店式截图;不放也行,市场会从 README 自动抽取。
许可
MIT
Plugins relacionados
dsh-web (dsh-ssh)
zhu1090093659/dsh-web
dsh-web (dsh-remote-web-ui)
zhu1090093659/dsh-web
dsh-web-ui (dsh-ssh)
zhu1090093659/dsh-web-ui
dsh-web-ui (dsh-remote-web-ui)
zhu1090093659/dsh-web-ui