Repository navigation
Releases: nikonotnicotine/Uranus_Imessage
Releases · nikonotnicotine/Uranus_Imessage
Release list
Uranus v1.16.13
Uranus v1.16.13:收附件慢是 HTTP/2 窗口没配,不是带宽
100M 宽带收一张 3.5MB 的图要几分钟。量下来(scripts/diag-attach-speed.mjs,
同一条线路同一分钟):
一元往返 RTT 中位 267ms
上行 4MB 1807ms = 2267KB/s ← 链路没问题
下行 3.1MB 28781ms = 127KB/s ← 慢 18 倍
下行那条流是「每块 256KB、块间固定停 2.1 秒」。RTT 才 0.27 秒,所以既不是
带宽也不是延迟,是 HTTP/2 流控窗口:吞吐上限 = 窗口 ÷ RTT,而 grpc-js 在没
传 grpc-node.flow_control_window 时窗口是 Node 默认的 65535 字节。我们一个
channel option 都没传过。
窗口抬到 8MB 之后,同一个附件 28781ms → 1890ms,5032KB/s。
补在 http2.connect 上而不是传 channelOptions:收消息的主链路是
@spectrum-ts/imessage,它在自己的 createCloudClients 里硬编码调
createGrpcClient,没把 channelOptions 透出来,而 ESM 的导入绑定从外面替换
不掉。补这一层还省掉改 node_modules —— 小手机是给别人部署的,node_modules
补丁一次 npm install 就没了。流级和连接级两个窗口都要抬,少一个都不管用。
小手机那边直接跳过:Workers 没有 node:http2,所以 import 放在判断之后动态做。
顺带把 STALL_MS 改回 60 秒。之前为了迁就 13KB/s 把它抬到 180 秒,那个前提
本身就是这个 bug;现在重下 3MB 只要 2 秒,掐掉重来重新变成划算的选择。
识图识出一片黑:流提前结束(不报错)时我们拿半份 JPEG 往下走,ffmpeg 把缺
的部分填成死色、退出码还是 0。实测截断到 15% 的图压出来 85% 画面是死色块。
加三道闸:readBytes 跟 SDK 报的 size 对账、识别前验尾标记(JPEG 的 FFD9 /
PNG 的 IEND)、ffmpeg 退出码 0 也读 stderr 认 EOI missing。对账留了 4KB 余量
且重试耗尽时不抛错,免得口径万一不符就把每张图都毙掉。
强制分隔两处:空格不再当切点(它在句子内部不是句子之间,see you tomorrow
会碎成三条);方括号支持一层嵌套,[audio_message:[whispers] …] 以前会碎成
五条文字发出去 —— media.js 的 BRACKET_BODY 早就支持嵌套了,这边没跟上。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uranus v1.16.12
Uranus v1.16.12:同步到日记的字数也跟着「每轮最多带」走 日记待总结那条一直是写死的 1500 字,「每轮最多带」只管了同步到私聊。 两条现在走同一个 injectWidth(每条正文的截断长度也跟着总字数走)。 设置里把「每轮最多带」挪成单独一组:只开日记不开私聊时原先看不见它。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uranus v1.16.11
Uranus v1.16.11:查手机分批生成不再整批失败;IG 图片进备份那一块 - 查手机一键生成按每轮 4 个 App 分批调模型,一批一落盘,某批失败不拖累别批; 回复被截断时把写完的那部分抢救出来 - instagram/media 从「聊天与记忆」挪进「表情包、参考图与 IG 图片」 - 「每轮最多带」最大 99999 字、默认 3000,数字可直接输入,正文截断长度跟着走 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uranus v1.16.10
Uranus v1.16.10:拉模式也用两步校准;小手机下载实验文件改走 fetch 用户问「为什么本地部署的共感娃娃没有校准模式」—— 拉模式只有老的单步「读 6 秒」, 把峰值均值摆出来让人自己填。现在 /api/doll/calib 两种模式通用:推送模式截住推过来 的数据,拉模式后台跑 calibrateDoll(现在顺带回原始读数,好算 p95),结果放同一处, 面板一套 DollCalib。老的 DollCalibrateButton 和 /api/doll/calibrate 删掉。读不成时 把原因放进结果,面板那一行直接显示。 下载实验文件以前是 location.href 整页跳转。桌面版同源没问题;小手机控制台在 pages.dev、后端在用户的 Worker 上,要靠 Service Worker 截住导航再转发,那条路在 iPhone Safari 上没验证过,失败了整页变成一屏 JSON。改用 apiDownload(fetch+blob), 和备份导出同一条已验证的路,出错在按钮下面报。 另外本地起小手机 Worker 验过:/doll/hug 能穿过 Worker 到后端。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uranus v1.16.9
Uranus v1.16.9:上下文存整句系统提示;去掉「手机连上来了吗」那块牌子
上下文里以前存的是 [共感娃娃被抱了一下] 占位,照的是提醒的写法 —— 提醒的提示词
长、每轮重发浪费。共感娃娃这句本来就短,而且时长、力度、次数就是这件事本身,
角色之后翻上下文该看得到。用户也问了「为什么不是那句系统提示」。toHistory 改成
toModel;{{user}} 照旧在 prompt.js 拼历史时由 applyVars 换。
按用户要求去掉面板上的状态牌和地址提示,连同只为它服务的 /api/doll/status。
lastDollPush 留着,「手机连上来了」那句日志靠它判断。e2e 第 6 节改成看日志。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uranus v1.16.8
Uranus v1.16.8:推送模式下状态每几秒被清一次,抱了永远结算不了 实机日志一串「有动静了」,每行隔 5~6 秒,后面既无「被抱了一下」也无「不算抱」。 根因:hugTick(给拉模式用的后台循环)把 mode === "push" 也算进「闸没过」, 顺手 createDollState() —— 而推送模式用的是同一份 dollWatcher.state。一抱就被抹。 推送模式下这条循环现在不碰状态。 第二个:抱完点 phyphox 的停止,后面一包都不来,判「放下」要收到的那几秒安静 永远收不到。加 doll.js:flushSilentHold:手机 silentMs 没发、还停在「抱着」就按 同一套规则结算(settleHold 抽出来两处共用)。 这个 bug 以前测不出来:那条循环只在 iMessage 连接起来时才跑,本地自测没有连接; e2e 推得又太快。现在推送口也带起那条循环,e2e 新增两节按真实节奏推。把旧 bug 临时放回去验过,新那节确实会挂。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uranus v1.16.7
Uranus v1.16.7:「不算抱」说出来,加两步校准替用户算阈值 实机日志一串「抱起来了(这一下 2.02 / 3.38 / 21.26)」之后再没下文,像卡在 「等放下」。其实每一下早就结束了、被判成「不算抱」—— 抱住后手机几乎不动, 算出来只动了零点几秒,不够默认 1.5 秒;而这句判定写在 debug 级别,看不见。 用户原话:「我不懂物理也不懂这些数字是什么意思」。 - 「不算抱」改成 logInfo + 人话(持续了几秒、要几秒、去做校准); 「抱起来了,等放下之后结算」改成「有动静了,看看是不是一次拥抱」。 - 推送模式两步校准:面板两个按钮(放着别碰 / 点完马上抱住),各截 8 秒 推过来的数据,doll.js:suggestThresholds 算出阈值,一键填好。开窗后第一包 丢掉 —— 它装的是点按钮之前那两秒。 - 「还抱着」线压过放着时的峰值而非 p95:判放下要连续安静几秒,被偶尔的跳点 越过就永远安静不够。最短时长降到 0.8 秒。 - 面板写明 iPhone 上 phyphox 读不到接近传感器(实测导出那一列为空)。 自测 test-doll 198(含用这位用户真实读数验校准)、test-doll-e2e 34。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uranus v1.16.6
Uranus v1.16.6:共感娃娃在每个关口都吭一声 「抱完控制台什么反应都没有」被问了好几次。根子是推送成功时控制台一个字都不打, 只有认出拥抱或被挡下才说话 —— 「推到了但还没认出」和「根本没推到」一模一样。 - 手机连上来时(开机首包、或断开一分钟后又来)报一声,只在状态变化时说。 - 抱起来那一刻就报,不用等放下结算完。 - 连续算「抱着」超过 30 秒提醒一次:多半是「还抱着算几」低于手机静置时的晃动, 放下了也结束不了、要等十分钟封顶。提醒里带当下读数。 - 推送地址支持 GET:用手机浏览器直接打开,回「通了 / 密钥不对」的人话, 打不开就是网络那段。功能没开照样 404。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uranus v1.16.4
Uranus v1.16.4:推送没反应时,让控制台自己说得出为什么 推送模式最难受的是「没反应时看不出为什么」:手机上点了播放、控制台一声不吭, 只能挨个猜。实机上连着卡了三次(总开关点不到、吊着等模型、实验文件里的密钥 过期),每次都靠猜。 - 面板上加一块「手机连上来了吗」,3 秒一刷,抱一下就能看见数字跳。分三种: 一个包都没到过(那是网络那一段,不是开关阈值)、到了但被挡下(直说是哪 一种,密钥那条还提醒「文件是不是改配置之前下的」)、通了(多久前、几个 样本、认出几次)。 - 同一块牌子列出这台机器自己看到的局域网地址 —— 实验文件里的地址不会跟着 机器换 IP 而变,对一眼就知道。顺带写明别填 localhost:手机连不上它, 而控制台地址栏里偏偏就写着它。 另外修一个被 e2e 测出来的真 bug:**没有角色在听的时候,整包数据被直接扔掉**。 以前在「没人听」那步就 return,连状态机都不喂。后果是桥接重连那几十秒的样本 全丢、状态接不上;而且这条路**没法在本地验证**(本地起后端没有 iMessage 连接, 听众永远是 0)。现在照常喂、只是不往外递;真认出了却没人听会明说一句。 新增 scripts/test-doll-e2e.mjs:起真后端、下真实验文件、照文件里写的地址和 密钥用假手机推,一路验到「认出几次拥抱」。纯函数那层测不到这些 —— 实机踩的 几次坑全是接起来之后才出现的。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uranus v1.16.3
Uranus v1.16.3:推送口别吊着等模型,乱序也别当成「清空了实验」
实机日志:一秒钟刷四条「实验时间归零了」、连抱两次只认出一次、手机上弹
「Could not retrieve data / 網路連線中斷」。三个症状同一条链。
根因是推送口 await 了整个递送。递送 = 一整轮模型调用,实测十几秒;而手机
每两秒推一包。于是:
- phyphox 等不及,报网络中断;
- 堆着的几包后来一起涌进来,到达顺序不一定是发出顺序;
- 状态机收到「时间比上次还早」的包,当成用户在手机上清了空,把正在进行的
那次拥抱整个推倒 —— 第二次拥抱就是这么丢的。
修法三条:
1. 喂状态机同步做完(纯算术,很快,而且只有同步才能保证按到达顺序喂),
然后立刻回 200;递送排进一条链在后台一个一个来。
2. 时间往回走不再一律当「重来」。先只滤掉已经见过的样本,连着 3 包整包都是
旧的才认定是真的重来 —— 真重来是不可逆的(此后每包都旧),乱序只坑一两包。
时间轴回到 0 附近那种一眼能认的照旧立刻重来,不白等。
3. 冷却期压下的那次拥抱改成 logInfo。以前是 debug,控制台一个字不说,
而从用户那头看「十分钟内已经说过一次」和「压根没认出来」一模一样,
只会以为功能坏了。线下 / 协助模式挡下的同理。
自测 182 项,新增 4 组专钉乱序。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>