Skip to content

Releases: ssamurias/dsh-fish

v0.7.2:修 0.7.1 之后 Linux 上还剩的一条测试

Choose a tag to compare

@ssamurias ssamurias released this 28 Oct 23:28

v0.7.2 — 最后一条只在 Windows 上绿的自更新测试

功能与 v0.7.0 / v0.7.1 完全一致,产品代码零改动。这一版只修 CI。

现象

0.7.1 推上去之后,Windows job 绿,Linux 三个 job 还剩一条红:

not ok - 非桌面版(execPath 是 node)不许装:没有能重开的目标就等于把人关在门外
error: 'spawn cmd.exe ENOENT'

原因

测试里把 exe 写成 'C:\Program Files\nodejs\node.exe'(反斜杠)。产品那条判断是「path.basename(exe) 是不是 node / node.exe」:

  • Windows 上 path.basename 认得反斜杠 → 得到 node.exe → 走进「不是桌面版」分支,测试通过。
  • Linux 上反斜杠不是分隔符 → basename 是整串 → 判不成 node → 继续往下真的去 spawn cmd.exe → ENOENT。

修法

exe 改成 'C:/Program Files/nodejs/node.exe'(正斜杠)。path.basename 在两个平台都认正斜杠,两边都稳定走进「不是桌面版」分支。

验证

  • 本机全量 node --test:883 passed / 0 failed。
  • 本机 test/selfupdate.test.mjs:28/28。

升级

和上一版一样:设置 → 插件 →「检查更新」,或把 profile 里那条依赖指到 github:ssamurias/dsh-fish#v0.7.2。装的是开发版(link:)的机器不会走自动升级。

v0.7.1:只修测试里的平台假设(功能与 v0.7.0 一致)

Choose a tag to compare

@ssamurias ssamurias released this 28 Oct 23:25

v0.7.1 — 只修测试里「只在 Windows 上成立」的假设

这一版没有改产品代码,功能与 v0.7.0 完全一致。修的只是 v0.7.0 推上去之后 GitHub Actions 上 Linux 三个 job 红的四条测试。

为什么 v0.7.0 的 CI 会红

四条失败全在测试里,是「本地 Windows 绿、Linux 红」的平台假设:

  1. restrict 的一条用例把 herDir 写成了 'C:\h'(JS 里反斜杠被吃掉,真值是 C:h),而 cwd 写的是 'C:\\h'(真值 C:\h)。Windows 上 resolve('C:h') 恰好归一回 C:\h,所以一直绿;Linux 上会拼到 cwd 后面,两个路径不相等,测试里那段逻辑根本没被触发。
  2. 自更新的一条用例用 pathToFileURL('C:/Users/…') 造 URL,Linux 上会把盘符当相对路径拼到 cwd 后面。
  3. 两个安装用例没显式给 platform,而 install() 先查「是不是 Windows」再查「有没有可重开的 exe」,Linux 上先撞前一条,拿不到预期的错误。

改了什么

  • 路径两边写同一种字面量;profile URL 用字面 file:///C:/… 并在断言时把 /C:/… 归一成 C:/…。
  • 安装用例显式传 platform: 'win32'。

验证

  • 本机全量 node --test:883 passed / 0 failed。
  • 另用 path.posix 复算了上面两处判据(normDir 相等、profileDirOf 归一出 C:/…),确认 Linux 上也会过。

升级

和 0.7.0 一样:设置 → 插件 →「检查更新」,或者手动把 profile 里那条依赖指到 github:ssamurias/dsh-fish#v0.7.1。装的是开发版(link:)的那台不会走自动升级。

v0.7.0:合并 21 个版本的更新(请神、出门、纪念品、旅行日记、日记与自更新)

Choose a tag to compare

@ssamurias ssamurias released this 28 Oct 23:19

把 0.6.12–0.6.32 二十一个本地版本合并成一次发布:对外只发这一版,安装/升级一次就能拿到全部改动。

这段时间修了什么、多了什么

请神(临时上身到你在用的那条对话)

  • 选择框显示真实对话名,不再是会话 id 的一串字母数字;重名会补上工作区目录名,没名字写「还没起名字的对话」。
  • 结束请神会往那条对话里补一句交接(「大肥鱼回去了,这条对话还给你」),下一轮它不会再顺着自己上一句「我是大肥鱼」接着演。请神段本身每轮重新组装、结束即撤,残留只在你俩的聊天历史里——想完全干净,开一条新对话。
  • 删掉了「临走留一句」输入框:那个框读起来像她要留话,其实是让你替她写字。

出门(去别的工作区干活)

  • 状态条与出门页会写清「此刻在外面:哪个工作区 · 已多久」,以及是哪条对话、第几趟。
  • 可以「接着上次那趟」:回到同一条会话里继续做(这版宿主走 resolveAgent,不是 resume)。
  • 回家那一刻当场拆掉身份段与兜底守卫,不等进程退出;失败会把这趟撤掉,不留「幽灵出门」。
  • 被拒收的那趟不再是死路:会留一张「上一趟没结算:文件对不上」卡,文件还原后点「复核一次」就能收下,结束时间仍是她真正回家的那一刻。
  • 驳回的条目会真的讲给她听;她说过的「写一句今天的想法」这类内容,出门前说的不算这趟,出门后说的才算。
  • 纪念品:她可以问「这个能不能带回去」(一趟最多 3 次、同时只 1 件等你点头),只认这趟工作区里的文件,目录/链接/空文件/超过 20MB 都拒;你点头才复制进 keepsakes/<日期>/。
  • 旅行日记:日记还是写同一本 diary/<日期>.md,但会打上这趟的标记,出门页按趟显示「日记 N 篇」。

工具面与白名单

  • 提示词多一段「手边有什么」:挡不掉的工具,至少让她不把它们当成自己的。
  • 白名单能写 ops_* 了;任何插件挂进她自己那一层的工具都能进白名单、都能被守卫放行。

日记、留话与住处

  • 「三天一篇日记都没有」修好:身份文档补上「用 growth_commit 交 type=diary」,每天最后一次叫醒给一句「今天到这里了」(写不写仍由她)。
  • 排队的留话/驳回话术会被真正投递(原来 deliverQueued 没有调用点,永远躺在文件里)。
  • 同一天写第二篇日记不再覆盖第一篇,接在后面,中间一行 ---。
  • 把会话从「已归档」放回来之后,插件自己认回来继续用那条,不再挂着「会话被收起来了」。
  • 「她写的小纸条」从记忆页搬到住所页,名字与单位也换了。

升级与稳定性

  • 设置页「检查更新」不再只把你送到 Releases:能直接下载 tag 包、核对包名与版本、备份 profile、替换、失败回滚并自动重开。开发版(link: / file: 依赖)会明确拒绝自动升级。
  • 修掉一个会污染真实账本的测试问题:全量测试曾把 20 个临时家写进 ~/.dsh-fish-homes.json,导致每次启动都记一条假「家换了」。测试已改指临时账本,默认账本对临时目录直接跳过;账本里那 19 条临时记录已清理(原文件备份为 .dsh-fish-homes.json.bak-20261029)。

关于「出门」页签

对外发布版仍然不显示这个页签:判据是数据目录里的 .dev 文件或环境变量 DSH_FISH_DEV=1,.dev 不随包发布;正式安装读不到就不渲染。开发/测试那台有 .dev,所以会看见,这是预期的。

升级方式

  • 市场里更新到 0.7.0;或
  • 设置 → 大肥鱼 → 检查更新 → 下载 → 安装(会关掉 DSH、约半分钟后自动重开);
  • 也可以用 GitHub 自更新以外的方式:pnpm add "github:ssamurias/dsh-fish#v0.7.0"。

回归

全量 node --test 883 passed / 0 failed。逐版本的细节见 CHANGELOG.md(0.6.12–0.6.32 条目保留在 0.7.0 之下)。

v0.6.11:出门页签在正式版藏住了

Choose a tag to compare

@ssamurias ssamurias released this 28 Oct 16:13

修了什么

「出门」页签在正式版里没藏住,装完就能看见。 上一版说它是「开发副本才显示」,其实没做到。

旧的判据是:插件自己的文件路径里有没有 node_modules 这一段。这个判据靠不住——发布包被解包到插件目录、或者目录经 junction / link 指过去时,路径里根本没有 node_modules,于是插件一直以为自己是「开发副本」,把「出门」页签也画了出来。

现在改成看数据目录里有没有 .dev 文件(或环境变量 DSH_FISH_DEV=1),跟「去刷 B 站」那个按钮用同一个开关:

  • 没有 .dev → 正式版,设置页只有「插件 / 原理 / 数据 / 反馈」四个页签,出门相关的东西一个都不出现;
  • 有 .dev → 本机测试版,跟以前一样能看见「出门」页签。

出门、请神这些功能的代码一行没删,只是入口在正式版收起来了。

怎么升级

装的是 link: 或从源码目录加载的,改完重启 DSH 就生效,不用重装。数据目录里 C:\Users\DANG\.dsh-fish\.dev 若还在,本机看到的仍是测试版;想验证正式版的样子,把它改名即可。

自检

本机 node --test:780 passed / 0 failed。回归用例会盯着这个开关不许再按安装路径猜。

v0.6.10:搬家界面、反馈页、出门与请神预览,三个 issue 与一批修复

Choose a tag to compare

@ssamurias ssamurias released this 28 Oct 15:07

从 v0.6.1 到这一版中间隔了 9 个版本号,但只发过 v0.6.1 的 Release——0.6.2–0.6.8 的改动一直攒在本地,随 0.6.9 一起推上来,那条更新记录也只写了三个 issue 和两处界面,把中间新增的东西全漏了。这条重写一遍,按「新增 / 界面 / 修了什么 / 升级须知」列。


一、新增

搬家界面:整个家能搬到别的盘

设置 → 数据 → 「迁移工作区…」→ 选一个文件夹 → 「搬到这个文件夹」。

  • 复制之后逐字节核对;有一个字节对不上就整体失败,不会留半份数据,也不会改指针。
  • 核对通过才写住处:~/.dsh-fish-location.json(放在数据目录外面,搬的时候不会被自己搬走)。
  • 旧目录改名到旁边的 dsh-fish-backups/moved-<时间戳>/,不直接删;旧工作区注册清掉、旧会话归档。
  • 搬家要重启 DSH 才生效。环境变量 DSH_FISH_HOME 仍然优先于这份指针。
  • 会拒绝四种:没选/选了个文件、目标里已经有一份非空的大肥鱼、目标在现家里面、目标把现家套进去。

反馈页(设置页第 9 个页签)

  • 常见问题解答 12 条:逐字搬自作者那份文档(权限、接别的渠道、上下文撑爆、遗忘机制、对话认知条数、字数限制、换对话、找不到成长事件、看不了视频、加功能……),不是摘要。整页自带深浅两套配色、不引任何外部资源,断网也能看。
  • 找开发者:QQ 1264518494;交流群:二维码(插件自带 media/feedback-qr.jpg)。
  • 页签说明就一句:「插件有问题、有想要的功能,都可以说。」

她自己的日记,她现在能翻回去看

新增只读工具 her_diary(lib/herdiary.js):可以翻最近一篇、指定某一天、或者只列「写过哪些天」。

  • 只读,只认 YYYY-MM-DD,../ 这类路径传不进来;一次一份,正文截到 3000 字。
  • 和「主人能不能看日记」是两个开关,互不交叉:日记仍然不进事件流、不进 her_recall,原来那条设计没被拆。

出门(预览,发布版不露入口)

设置 → 出门:选一个工作区,派她去那儿干一趟活,回来再判这趟算不算数。

  • 换的是规矩,不只是地方:继承那个工作区原有的工具与权限;一次只能出一趟;出门期间家里的日程整段暂停。
  • 出门那一刻,身份文本归档成只读快照,外面读快照,不读家里那份随时可改的文件;同时挂兜底守卫——任何工具调用里出现她家目录的路径(~/.dsh-fish、~/.dsh/memory、.dsh/sessions、.dsh/profiles)就拒绝。这层不是防外人,是防「自己伸手回家」。
  • 回家先验事件流:比对字节数与尾部 4096 的 sha256,结论分「变小 / 原地改写 / 只是追加」三种,前两种默认不收。回家卡把这一趟新增事件逐条摊开(默认全勾、截 400 字,顶回来的单独标),驳回只标 rejected,原文不删。
  • 出门口袋:默认 ~/outing-pocket 的空目录,避免工作区记忆注入把家里的禁令原文带出去。代价也写在界面上:口袋里写不进 02/03/04 这些中文祖先路径。
  • 这一版发布包不显示这个页签(服务端按自己的 import.meta.url 判断是不是装在 node_modules 下,本机 link: 的开发副本照常显示)。代码、路由、审查卡全部保留,不是删功能。

请神(预览,同上收在开发副本里)

把一条正在用的对话临时交给她:从下一轮起回你话的是她,身份是真的、工具是真的,不是演;结束时撤销,那条对话恢复原样。

  • 做法是覆盖宿主的人格段(deployment:persona-prefix / deployment:persona-suffix,拿不到就退到 fish:possession),撤销靠 scoped effect 逆序 dispose,可验证地恢复。
  • 三条边界:只能请活着的对话;她自己的家不能请;出门时不能请。请神期间同一条对话分不出谁在说话,工具面对你也不可用,守卫连你一起拦,只能由你结束。
  • 台账在 ~/.dsh-fish/possessions.json,冷会话在 agent/created 时补挂;身份用请神那一刻的快照。

导出的运行记录补全了四样

另一台机器上「看不了视频画面」却只能靠猜,现在「设置 → 数据 → 导出运行记录」里多了:

  1. 实际生效的 allow 列表(不只是配置里写的名字),并标出名单里没生效的、各自是 applied / applied-late / deferred / failed;
  2. 模型与图像能力三态(支持 / 不支持 / 说不准),来自 lib/modelinfo.js;
  3. events.jsonl 尾部 60 行 / 256KB;
  4. 看画面每一步的日志(设置关 / 非法视频号 / 额度满 / 抽帧失败 / 成功时带 used+1/cap)。

二、界面变化

  • 常见问题解答点了没反应 → 就地展开。 原来是个 target="_blank" 链接指向 /dsh-fish/faq,而宿主的信任栅栏只认 App 内的登录 cookie,新标签页直接访问一律 403。现在是按钮 + 卡片内展开的面板(向 /faq.data 取同一份内容),面板内滚,看完点「收起」。整页 HTML 仍保留。
  • 看视频历史记录会翻页,每页条数跟着实际量自适应。 摊平成一条一条、日期只在换天处出现一次;一共 ≤ 8 条就一页全放下(连翻页条都不出);日均 > 20 条 → 6 条/页,> 10 → 8 条,> 5 → 10 条,其余 12 条。页码旁写「一页 N 条」。
  • 「会话被收起来了」单独一张卡,旁边就是「重新搭一間」——不再藏在「重置」里,免得以为只能重开一局。
  • 换 root 会留痕:数据页顶部提示,事件流里有一条 meta(「家换了:A → B。这不是搬家……」)。
  • 自检里「看画面」独立成一项,判据按证据强弱分四档(全局表看到 → 绿;收窄后名单里有 → 绿;宿主明说没挂 attachments → 红并给三步修法;都查不到 → 绿并写「查不准」),不再和别的项混在一起。
  • 状态卡不再每分钟刷「醒了,但今天没有该问的事」(quiet: 一天一条,读取按本地时区折叠);skip 日志也不再每分钟一条(同小时同原因只记一条)。

三、修了什么

仓库里的三个 issue(#5 / #6 / #7)全部修完并关闭:

  • #5 一次 -412 被放大成 30 分钟不可用:熔断拆成读 / 写两档(读 60 秒起、翻倍、封顶 10 分钟;写 5 分钟起、封顶 30 分钟,成功即解除自己那档);WBI 签名接口收到 -412 先刷密钥重试一次;-352 / -509 一起按风控处理;请求间隔 minIntervalMs / jitterMs 可配;顺手修了取帧路径匿名请求的毛病(现在先读 owner.json 的 cookie)。
  • #6 侧栏直接聊天轮数不涨:新增 lib/turns.js,监听宿主 session/event,只统计真人打的消息(按 clientTimeZone 判、按 rpcId 去重),turn/end 再结账,满了照旧换会话并留 meta。
  • #7 同日第二篇日记静默覆盖、她自己读不回:覆盖前旧稿归档到 diary/archive/YYYY-MM-DD-HHmmss.md;新增只读 her_diary(见上)。

其他修复:

  • 出门兜底守卫「看不见实参」:它只读 exec.args / input / params,而宿主的 createExecution 只挂 exec.arguments——守卫每次拿到空对象,日志写着「挂上了」其实一次没拦(真机上就用 ops_bash 把 PLAN.md 读走过)。现在四种形状都认。
  • 出门的顺序 bug:先建会话再记账 → agent/created 同步触发时读到「没出门」。改成先记账再建会话,bindOutingSession 幂等,abortOuting 撤空壳。
  • 日记开关被整表自动保存拨回:三项改走窄 patch({diary:{visible}} 等),只提交改的那一格。
  • 领养人两格被登录账号顶掉:cookie 解析失败也保留手填的两个格;测试按钮改名「测试 cookie 能不能说话」;脏值直接提示。
  • 看视频记录只看得见 4 条:单条 meta 1800 字上限把后面截掉了,改成分片写 browse: / browse-more:。
  • 风控提示说不清:补上剩余分钟;观测台区分「落盘冷却」与「进程内 60 秒熔断」。
  • 递过来的视频她永远评不了:评论目标改成「刷站 ∪ 当天 look: ∪ 当天 watched:」,口径是她有没有真的看过,不是谁让她看的;bili_look 新增 what=video(BV 号或短链)。
  • 两份大肥鱼共用一个家:instance.json 租约(15 秒心跳、45 秒或死进程即接管),后进来的不写;每条事件带 sessionId;写前核对 cwd 属不属于这个家。
  • 归档被自动重建 / 并发双建 / 换 root 无痕:归档记 status:'archived' 不再重建;同一 root 建会话加单飞锁 + createdAt 10 分钟宽限;换 root 写 ~/.dsh-fish-homes.json 并留痕(见上)。
  • 只有 Windows 上成立的路径判断(0.6.10):normPath / isInside / normRoot 在 POSIX 上会把 D:\a\home 当相对路径、也不认 \ 结尾,导致 GitHub Actions 四个 job 全红;自检断言还把「没装 ffmpeg」连坐成「看画面坏了」。都已修,Windows 上的输出格式一字未变,已经记下的家不会被判成「换了家」。

四、升级须知

  1. 归档的意思变了。 以前「归档会话」= 下次启动重开一间;现在归档就是收起来,想重开要点设置页的「重新搭一間」。
  2. 【turns】 不回填。 升级前已有的对话从升级那一刻重新累计,旧 home.json 直接兼容,不需要迁移。
  3. 出门 / 请神在发布包里没有页签。 服务端判断自己装在 node_modules 下就回 dev: false,设置页不渲染;本机 link: 的开发副本照常显示。功能代码与路由都在。
  4. 给手工搬过插件文件夹的人:正确的分家方式是在 profile 的 cordis.patch.yml 里给这个插件条目配 root,两个工作区各指一个目录,不要复制插件文件夹。升级插件包不会重写 cordis.patch.yml;升级后确认那条 loader 条目的 id 还对得上,对不上 patch 会静默失配。
  5. 想整个盘子换地方,用「迁移工作区…」(见一),不要再用文件管理器拖。

安装 / 更新:先关掉 DSH(运行中替换已加载的包会 EPERM),再

"<DSH>/resources/runtime/cli/bin/dsh.cmd" plugin --profile <profile> add "github:ssamurias/dsh-fish"

然后重启。数据目录 ~/.dsh-fish/ 不受影响。想先看有没有新版:设置 → 插件 → 检查更新。

这一版的验证:本机 node --test 779 条全绿;GitHub Actions 四个 job(Windows + ubuntu 20/22/24)全绿。

v0.6.1:叫醒先说清时间,修社区两个 issue

Choose a tag to compare

@ssamurias ssamurias released this 27 Oct 16:22

v0.6.1

这一版把 0.6.0 之后攒下的改动一起发出来。没有新增人格设置,也没有改「通过事件长大」这条主线——全部是让她在第一次醒来、第一次伸手时少犯错。

叫醒的时候,先说清现在几点

  • 手动点「叫醒大肥鱼」时,她的处境开头会写:「现在是 16:06。有人刚按了叫醒——这个点不在你平时的时段,是有人要你现在醒。」
  • 定时唤醒则是:「现在是 20:43,这一次是你自己醒的。」
  • 屋子刚建好、还没有对话时的第一声触发语,也带上了时间和「屋子刚建好,有人叫了你一声」。

之前没有这句,她会在下午被叫醒时自己猜「大概不是我的时段」,然后坐着不动。

身份文档补一句「屋里只有这几样」

她的身份文档「我手上有什么」现在会说明:屋里只有这几样,不是被谁拿走了;别的东西伸手也够不着。原来她容易把工具收窄理解成权限事故。

QQ 接入写进说明

设置页「手上能用什么」的白名单卡里加了「QQ 接入」一段:装一个社区现成的 QQ 桥接插件(比如 qq-bridge),把 qq_send_message / qq_get_unread_messages / qq_reply 填进白名单即可;本插件不直接提供 QQ 桥接。白名单里放行的工具名会被念进她的身份文档——否则她不知道自己多了这几只手。

修:启动时工具面被误收窄成 1 个

社区真机反馈:宿主还没登记完她的工具时,旧实现会把白名单和报错里的已知名单取交集,交集只剩 1 个,那条会话从此调 bili_look 报 unknown tool,她答「我没法浏览 B 站」。现在改成:这一次先不收窄(兜底守卫仍在拦),每 200ms 轮询等宿主登记齐了再收;等不齐就留到下次会话,不会再把工具永久砍掉。

修社区 issue #3 与 #4

  • #3 事件流变长后卡 JS 主线程:mentions 与 detectTensions 改倒排索引 + 长度上界剪枝,stability 加结果缓存;相似度的定义没变。本机基准:deriveSelf 800 条从 14.9 秒降到 51ms,stability 冷算 501 条约 0.5 秒、缓存命中 0.01ms。
  • #4 素材没取到时提示词仍承诺「下面附素材」:三条事件模板改成只描述处境,真取到素材时由处境段自己说明。

测试

node --test --test-isolation=none = 647 个测试 / 645 过 / 2 条已知跨文件假红(单文件跑都绿)。


对应提交:4f01ed8 叫醒文案、8ee4a63 工具面时序、9604b1e QQ 接入、91ea8d9 AGENTS 第 7 节、c1cef28 issue #3/#4、8886ce2 与 1779013 文档清理。

v0.6.0:领养人与登录账号拆开,首批不再固定四条

Choose a tag to compare

@ssamurias ssamurias released this 27 Oct 05:15

这一版把两件事一起发出来

1. 领养人和登录账号拆成两个人

以前只要存一次 cookie、或者点一次「测试能不能说话」,插件就拿 cookie 探到的 mid 与昵称覆盖「领养人认证」那两格。想用小号当她的嘴、大号接收 @ 的时候,评论里 @ 的是小号,手填的大号还会被冲掉。

现在 owner.json 多一格只读的 account(mid / name / savedAt):「这份 cookie 登的是谁」只记在这里,存 cookie 和测试都只写它,绝不碰领养人。领养人只由你手填,决定评论里 @ 谁。判断「哪条评论是她自己补的」改用 account.mid,老数据没有 account 时仍退回原来的 mid。

界面:领养人卡片写明「这是要 @ 的账号,一般填大号,和 cookie 无关」;cookie 卡片只读显示「登录账号:xxx(uid …)」;点「测试能不能说话」不再把输入框改成小号;自检的「B 站登录」显示登录账号,而不是领养人昵称。

2. 重置后的首批不再固定四条

以前阶段 1 只吃「入站必刷」——98 条全站老片的固定榜;而重置会清空事件流(seen 变空、阶段回 1),所以每次重置刷到的首批都是同样四条。

现在阶段 1 改成四路混:入站必刷 + 全站热门 + 全站排行榜 + 每轮随机抽 2 个分区排行榜(browse.rankingTids 可调,默认 2,0–4)。候选进排序前先打散,分数并列时的先后不再固定成接口顺序;分数不并列的仍按分数排。

分区池不含鬼畜(119)与番剧/影视类(拿不到正片)。

测试

641 条:--test-isolation=none 下 639 过、2 条已知跨文件假红(cover: fetchCover 拿不到图时返回空串,不抛、ULID 单调递增,且能从 id 反解时间),单文件跑各自全绿;CI 用独立进程跑,全绿。

v0.5.9:换一把量「她还是不是她」的尺子

Choose a tag to compare

@ssamurias ssamurias released this 26 Oct 21:10

0.5.9 — 2026-10-27

「判断漂移」原来那把尺子量错了东西

三个数里有两个是样本不足时的默认值被当成读数印了出来:刚重置的一局里她还没有判断(稳定 → 0)、说过的话不足两条(一致 → 1)、没有七天以前的老话(新鲜 → 0)。更要紧的是稳定那把尺子本身——它量的是「抽掉几条判断后 needs 三项变多少」,而 needs 是拒绝过几次、改口过几次这些内部计数器的映射,不是「她这个人」。刚开局的号里三项常年 0,抽掉谁都是 0,稳定永远是 0.00。

① 换尺子:稳定 = 抽掉几条她还在拿着的判断,她还是不是她。

新增 lib/quality.js:随机抽 k 条判断(连同源头事件),重算一遍自我描述,和原来的比相似度。接近 0 = 那些判断只是记账;接近 1 = 全押在少数几条上。比较前先剔掉「你是谁 / 现在 / 不能做的 / 你还不会的 / 他说的事和你记得的不一样时」这些永远不变的骨架段,否则分母被常数撑满。

② 样本不足时不再印假分数。

stabilityBand() 把「还没攒到判断,测不出来 / 只有 N 条判断,抽掉一条就是一大块 / 这些判断还只是记账… / 长在这些事上… / 全压在这几条上…」写成一句人话;一致与新鲜同样处理。数字只在真能测时才印。

③ 界面文案改口。

QUALITY_HELP 原来写「越接近 1 越好」——错的。这三个不是考卷分数,是体检值:稳定太高也是病(押得太死),一致恒为 1.00 也可能是她一直没长新东西。

三个值分三行显示:「判断漂移(三个诊断值,不是分数)」占一行做小标题,下面三行各自是「稳定 / 一致 / 新鲜」,每行右边一个 ⓘ 说清量什么。

能测出来时,数字跟判读一起印:0.16 · 长在这些事上,抽掉一条少一块。样本不足时仍然只给判读。

另:lib/derive.js 里的 stability 移除,改由 lib/quality.js 导出;lib/observe.js 的 /state 把 band 一并算好传出。

回归:634 条,631 过、3 条环境相关红(detectFfmpeg 在沙箱内 spawn 被拦成 EPERM、cover 与 ULID 的跨用例状态污染,均为本机运行环境问题,非 0.5.9 引入)。

0.5.8:让「回顾」带上凭证

Choose a tag to compare

@ssamurias ssamurias released this 26 Oct 19:36

让「回顾」这一步开始要凭证。

第一层:refs 要能对上,不只是写着

  • lib/schema.js 的 validateEvent 新增 knownIds 参数。revise 和 narration 的每个 ref 都必须在事件流里真实存在,否则 REF_NOT_FOUND。以前只查「非空」,于是「我改的是哪一条」很容易退化成仪式——随便填个 id 就过了。
  • lib/store.js 的 appendEvent 在 type 是这两种时读一遍全量事件、把 id 集合塞进 ctx;读失败退化成老行为(knownIds = null),不能因为查不了就拒收她正常的写入。

第二层:回顾型 narration 也要 refs

  • 要么用 refs 指到 her_recall 翻到的具体几条,要么直说「我没想清楚」。后者放行——那句本身也是真的,不该因为没想清楚就什么都不许写。
  • isBlankNarration():≤60 字且整句就是一个「没想清楚」的说法才算;拿它当开头再接一整篇自传不算,仍然要 refs。
  • her_recall 现在每行尾带 (ev_xxx)。没有 id,第二层就只是逼她编。
  • sleepPrompt / SLEEP_BRIEF / RECALL_BRIEF / growth_commit 的工具说明同步改。

第三层不做:很多「我变了」是弥漫性的,硬挂凭证会让回顾变成拼凑,产出更少而质量更难判断。

回归 630 条:独立进程 node --test 全绿;--test-isolation=none 下 628 过、2 条已知跨文件假红(cover、ULID,单文件跑都绿)。

0.5.7:导入别人养过的大肥鱼

Choose a tag to compare

@ssamurias ssamurias released this 26 Oct 18:43

0.5.2 → 0.5.7

从 0.5.2 到 0.5.7 六个版本一起发。下面按版本列,细节见 CHANGELOG.md。

0.5.2 称呼不再永远停在第一次

旧规则只认「称呼你」,他自己给名字、她自己改口都不算;而且只取第一次——于是她先说「开灯的」、后来接受「时梦尘」,设置页状态栏永远停在那个已经被否掉的旧称呼上。

  • 「称呼 / 叫你 / 叫他 / 他的名字是」都认了。
  • 后来的覆盖先前的。
  • 尾词剥壳与代词挡板(「的」不剥——「开灯的」是称呼本身,不是语气词)。
  • 顺带修三处过时注释:身份早改走 systemPrompt.section,不再依赖 home/AGENTS.md 与 cwd 链。

0.5.3 接一只别人养过的大肥鱼

  • 新增 lib/import.js 与 POST /dsh-fish/import:人设正文写进 seed 事件,称呼写 meta 事件,工具白名单取并集写 config。
  • 人设走事件不走配置(她以后能自己 revise);天数天然归第 1 天;只在还没有 seed 的一局生效,有起点就 409;不带天数、判断、疤、拒绝记录、日记、B 站登录。
  • 带过来的称呼让起名事件 name_offer 自然不再触发。
  • 设置页新增导入卡,逐条写明什么过来、什么不过来、不来会怎样。

0.5.4 豁免只认「导入」这一个动作

0.5.3 把豁免写成 config 里的 persona.bansMuted,而 config 会跟着「备份与恢复」搬回来 —— 原生养大的一只鱼只要恢复过一次「导入过」的档,就永久拿到豁免。

改成事件溯源:导入时写一条 meta 记录 import-mark:,deriveSelf 读它得到 model.persona.imported,身份渲染只认 model,config 里根本没有这组键。

物理层那两条(不读自身数值、不改自己)不受影响。

0.5.5 唤醒去重(issue #1 第二个问题)

wakeIfBlank() 靠 list() 猜「这条会话是不是空的」,但插件自己建的会话永远不是 current、进不了可见列表 —— 于是那条分支每次启动都命中,每次重启都白叫一声。

改成自己记账:叫成功后把 sessionId 写进 home.json 的 wokeFor。只记成功送达的那一次,抛错不写、下次重试。

0.5.6 「过来什么、不过来什么」写成用户能听懂的话

  • 逐条写细天数、判断、疤、拒绝记录、日记、cookie 的后果。
  • 新增「如果你原本带好感度这类设定」那段说明(是说明,不是控件)。
  • README 首段与市场文案同步「默认从空白开始,也可以导入已经在别处养过的那一位」。
  • 交接单模板可一键下载;模板与解析器的小节名统一成「你是谁」。

0.5.7 「下载交接单模板」不再挂在分支里

原来它写在「能导入、且已经展开粘贴框」那一支里 —— 已经养着一只鱼的人走的是另一条分支,页面上根本没有这个按钮。现在提到导入卡正文末尾,跟「这一局能不能接」完全解耦。


回归:625 条,623 过,2 条已知跨文件假红(cover、ULID,单文件独立跑各自全绿)。零依赖未破(三个依赖字段仍是 {})。