dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh-FEMO (Flow Emerges Opus) — dsh 插件版多智能体剧本引擎:Femo 会话、聊天窗口角色气泡、剧本控制(含完整引擎,整个文件夹搬走即用)。Private until scrub review.
Femo 是 Flow Emergence 的缩写。 把"像写剧本一样编排多智能体"的 Femo 引擎做成一个 DeepSeek Harness (dsh) 插件。 引擎、桥接器、插件代码、用户数据目录全在这个文件夹里——整个文件夹就是一个插件, 搬到哪里都能用,不需要任何外部 Femo 安装。
Femo 会话 = dsh 主模型会话 + 多智能体剧本引擎:
femo-mount 挂载到会话)、干跑自检(femo-debug,零 token 空跑)、运行剧本(femo-run);剧本运行时引擎拥有会话(pre-step 只在轮首步拦截 plugin 注入,不让引擎噪音把主模型叫醒),空闲时主模型照常可用;运行中你在主窗口跟主模型说话 = 完整的一轮原生对话(工具可以连调多轮,2026-09-11 起);戏内戏外不掺一轮:你这轮没说完时,剧本轮到你下场(含同节点重试)会先排队,等这轮收口再作为新一轮开场(2026-09-11 起)femo:docs section),先读文档再写,不凭印象猜语法ai / human / @mind 动态分发:同一节点按运行时执行者自动分流(AI 走 LLM 路径、人类等待输入),执行者由变量指向、运行中可切换剧本语言(.femo):meta / actors / code / vars / action / module / mainflow,支持 scope 视角隔离、par 并行、fork/join 网关、断点续跑、@mind 运行时分发。AI 角色可用 source 指定模型(source:模型id 走默认 provider,或 source:provider/模型id 完全指定;省略跟随主模型),编译期校验,写错立即报错(详见语法文档)。
dsh-femo/ ← 整个文件夹就是插件
├── hostAdapter/ dsh 接口侧(host/ 宿主进程 TS + client/ 聊天窗 bundle + python/ 桥进程,见 hostAdapter/README.md)
├── femoGen/ 可视化剧本编辑器(React/Vite)
├── femoToolcall/ AI 工具箱:femo_debugger / chronica / femo-chat
├── femoCompiler/ femo 引擎:parser / runtime / 并发 / SQLite 记忆
├── femoBridges/ LLM 桥 + getDir(用户目录解析)
├── femoExamples/ 示例与测试剧本(.femo)+ 伴生 @func 模块
├── user_data/ ★ 运行时数据:projects(你的剧本)/ memory(台账)/ host-history(会话显示:projections 投影窗 + drafts 草稿)/ jobs(后端 Job 状态)
├── host.manifest.json 宿主能力清单(thinking 档位/默认用户——接别的 harness 换这份文件)
├── build.mjs / package.json / cordis.patch.yml
用户数据自包含:数据库、剧本、checkpoint 都落在本文件夹的 user_data/ 下——整个文件夹打包/拷贝,数据跟着走。
本仓库目前为私有,公开后即可使用一键安装;当前请使用下方手动装配。
# 仓库公开后可用(安装时自动编译,包内含 prepare 脚本,装完重启 dsh web 生效):
dsh plugin --profile web add github:Phant0Meow/dsh-femo
# 1. 把整个文件夹放进 profile 的 node_modules(或 junction 指过去)
# e.g. ~/.dsh/profiles/web/node_modules/dsh-femo
# 2. 环境要求
pip install requests # Python 3 唯一必需依赖(引擎 LLM 调用)
# 3. 在 profile 的 cordis.patch.yml 注册
- insert:
- id: dsh-femo
name: 'dsh-femo'
config:
enabled: true
# 4. 重启 dsh web
配置里 femoRoot 可省略(缺省 = 插件文件夹自身);只有把引擎拆出去单独放时才需要指定。
| 键 | 默认 | 说明 |
|---|---|---|
femoRoot | 插件包根 | 引擎根目录(缺省自包含;单独拆分引擎时指定) |
python | python | Python 可执行名 |
provider / model / apiUrl | deepseek / deepseek-v4-flash / api.deepseek.com | 引擎 AI 节点的 LLM 路由(引擎内置桥) |
hostAiBackend | true | AI 节点走宿主子代理(原生工具调用 + 思考链);旧配置名 dshAiBackend 兼容 |
dshProvider | deepseek-official | 裸 id source 归属的 dsh LLM provider;空 source 跟随主模型(见语法文档) |
defaultActorTools | true | 角色未声明 tools: 时的工具开关;剧本里可逐角色 tools: true/false 或白名单 |
插件往会话日志写入自定义事件类型 dsh-femo/chat。历史加载需要 dsh 的事件注册面
(registerSessionEventType,dsh 官方注释预留的特性,未随官方版本发布):
dsh-femo/chat 事件的旧会话历史无法加载(dsh 拒绝
未知事件类型是设计行为)。新会话不受影响。让官方版也支持历史加载,只需把 dsh-femo/chat 加进 dsh 的已知事件类型白名单。
改动极小(一个文件一行),下面给出精确到行的操作步骤。
目标文件:@deepseek-ai/dsh-session 包内的 KNOWN_SESSION_EVENT_TYPES 定义处。
源码运行版(node --import tsx 启动的 dsh,文件在
packages/core/session/src/known-event-types.ts):
找到这个数组(第 19 行起):
export const KNOWN_SESSION_EVENT_TYPES: ReadonlySet<string> = new Set([
'agent-preset/selected',
'agent/inbox/spliced',
'approval/asked',
'approval/decided',
'approval/policy',
'assistant/chunk',
'assistant/message',
'command/done',
'command/run',
'compaction/end', // ← 在 'command/run', 和 'compaction/end', 之间插入一行
把:
'command/done',
'command/run',
'compaction/end',
改成:
'command/done',
'command/run',
'dsh-femo/chat',
'compaction/end',
npm 安装版(npm install 的 dsh,运行时加载的是编译产物):
node -e "console.log(require.resolve('@deepseek-ai/dsh-session'))"(或在
node_modules/@deepseek-ai/dsh-session/lib/ 下找)command/run(白名单数组就在它附近),找到形如
"command/run", "compaction/end"(或换行写法)的数组"command/run" 之后插入 "dsh-femo/chat"(保持数组语法一致)注意事项:
GENERATED ... do not edit by hand——手改可用,但 dsh 升级/重装后需要重打(升级后重新执行本步骤)registerSessionEventType API + coordinator 消费)合入 dsh——改动更正规、可随上游升级,详见本项目文档与 dsh 的 known-event-types.ts 头部注释("a registration surface ... deferred until such a consumer exists").femo 剧本放在 user_data/projects/(子目录或直接文件)。侧边栏 🎭 按钮新建 femo 会话,会话顶部「femo 剧本」面板选择/编辑/保存并运行;👁 视角切换(上帝/角色视角/🎬 戏外主模型)。
file: 文件放置约定剧本 code: 区通过 file:"xxx.py" 引用 Python 模块,地址按以下规则解析:
| 写法 | 解析 |
|---|---|
绝对路径,如 file:"D:/a/b.py" | 直接使用 |
相对路径,如 file:"utils/battle.py" | 相对剧本文件所在目录解析(不是项目根、不是 CWD) |
| 剧本未保存(纯文本运行)时用相对路径 | 报错:提示先「导出 .femo」保存剧本,或改用绝对路径 |
| 文件不存在 | 报错 Python Bridge: 文件不存在 <完整路径>(不静默兜底) |
官方示例 @func 模块只在 femoExamples/func_code/ 作为参考样本存在(首启自动复制机制已于 2026-09-12 移除,也没有任何全局回退查找位置)。自定义模块请放在剧本同目录(或子目录),与剧本一起移动。
写剧本不用怕演员演砸,运行时的错误各有个的去处:
max_retries 控制(默认 2 次)人类节点同样有容错:变量赋值不合法时输入框会带着错误提示重新打开,改到合法为止(同样受 max_retries 约束,超限按超时放行留痕)。
正式运行前先空跑一遍:femo_debugger.py 伪装成宿主(FakeHost),AI 动作与人类输入全部由调试器合成替答——不调用任何模型,引擎仍按真实管线跑完整流程(赋值校验、条件边、循环、par/fork、module、@func 落库全套走一遍),所以它既测剧本 bug,也暴露引擎 bug。
old → new / 合成赋值与来源 / 重试 / 告警)实时流进面板femo-debug 工具——把当前挂载的剧本干跑一遍,流水 + 终报(每轮结局与报错、节点执行顺序、边覆盖、变量快照 diff、未达节点)一次性回给主模型,写/改完剧本先自检再开演cache/debug-sandbox/,滚动保留最近 3 天)、可反复跑;同一时刻只允许一条干跑femo_debugger.py 文件头):run <剧本> --module 名 单测某模块、--set 变量=值 定向注入初始状态、--assign-prob 0.7 概率沉默、--flaky 0.3 注入无效赋值测重试链路、--runs N 多轮换种子每一次运行是一个独立的 Job,有自己的档案(user_data/runs/):跑到哪个节点、变量世界什么样、正在演还是被挂起,全记在里面。所以:
femo-run 工具有 fresh_start / pause / resume / list_jobs 四个动作——主模型可以自己列出历史 Job、把落下的戏续上(哪怕隔了好几场)备注:直连模式(不走 dsh 子代理、用引擎内置 LLM 桥)下 AI 调用失败时,演出同样走「挂起存档」而不是报错卡死;画布上显示的是「已暂停」,点「继续」即可重试该节点。
npm install
powershell -ExecutionPolicy Bypass -File scripts/link-workspace.ps1 # 建 @deepseek-ai 构建镜像(Windows junction)
npm run build # lib/index.js(host)+ lib/client.js(browser)
python hostAdapter/python/dev-bridge-test.py # 桥接器协议冒烟
Apache-2.0