Skip to content

Releases

flashCat 1.5.4:新增 flashcat 命令行与本地控制接口,概览指标改为按请求实测

Choose a tag to compare

@imi4u36d imi4u36d released this 11 Nov 07:00
8656241

flashCat 1.5.4

这一版把 CLI 与本地控制接口补上:flashcat 能列出/启停引擎、切模型、流式对话、
读日志与网关状态,应用没在跑时也能做离线操作。概览的取数口径同步重做:预填充
与解码优先读引擎按请求自报的 timings,量不出来就画「—」;第四格从内存压力
换成按 token 加权的缓存命中率。

前缀缓存改为落盘,重启应用不用从零预填充;切走对话不再中断生成,回到列表能点
回正在跑的那一段;应用内不再注册任何快捷键,键盘效率交给终端。

新增

命令行与本机控制接口

  • flashcat 命令行。 随 .app 分发在 Contents/Helpers/flashcat,.pkg
    安装时链接到 /usr/local/bin。支持 status、engines(list/start/stop/
    restart/use/install/uninstall/port/logs)、models(list/use/download/delete/
    path)、chat(stdin、流式、思考过程、JSON)、gateway、logs(级别过滤与
    --follow)、config、app、doctor、completion、cli。
  • 应用侧本机控制接口。 默认 127.0.0.1:9100,端口被占用时自动顺延;每次
    启动生成随机令牌,control.json 以 0600 保存。设置页新增「命令行接口」开关
    与端口。接口与推理网关分离,网关关闭时仍可驱动应用。
  • 共享路径与协议。 FlashCatPaths、EngineInstallations 与
    FlashCatKit/Control/ControlProtocol.swift 收进 Kit,应用和 CLI 使用同一套
    支持目录、模型目录、引擎发现规则与控制文档。
  • 命令行脚本契约。 结果型命令都支持 --json;结果走 stdout、进度走 stderr;
    固定退出码(应用未运行 3、找不到 4、超时 5、冲突 6、令牌 7);
    zsh / bash / fish 补全;--timeout、--quiet、--no-color。
  • 离线能力。 应用未运行时仍可 status、列出引擎与磁盘模型、安装/卸载引擎、
    读日志与读取/修改纯配置;需要应用的动作明确报错,不伪造成功。

前缀缓存落盘

  • 重启后不再从零预填充。 引擎的 hot prefix cache 只在内存里,App 一重启就
    清零,上一次会话的整段历史只能重算——同一段 1.5 万 token 的会话,带缓存
    恢复是 0.1 秒,重启后无缓存是 13.8 秒,十万 token 级能到 3 分钟。四家引擎
    本来都有这条 SSD 层,只是没人打开:Splash 的 --persistent-cache、oMLX 的
    --paged-ssd-cache-dir(不传这个目录它的前缀缓存等于全关)、MLX-Serve 的
    --prefix-cache-disk 默认都是关的,MTPLX 默认开着但恢复被自己的
    boundary 预算挡掉。现在引擎配置页有「前缀缓存」卡片:开关 + 磁盘预算
    (默认 20 GB),关闭后显式下发各家的 off 参数而不是留空。
  • 统一缓存根。 各家的落盘快照都收到
    Application Support/flashCat/prefix-cache/<engine>/ 下,容量、清理和备份
    只需要管一个目录。MLX-Serve 的路径写死在 $HOME/.mlx-serve/kv-cache、没有
    对应开关,用符号链接指进来。
  • 模型搬家不再作废缓存。 缓存条目按模型的绝对路径做键,所以
    ModelStorageMigration 把权重从 ~/.mtplx/models 搬进应用目录时,该模型
    已有的快照全部失配——实测 23 个条目、约 29 GB 从此再也命中不了,
    同时同一个模型在新路径下有 0 命中。迁移现在改写 manifest 里的 model_path
    而不是放任它变孤儿,并把 ~/.mtplx/session-bank 一并搬到新根下。
  • 测试:PrefixCacheTuningTests 钉住每家的参数拼写(Splash 只认 20G,
    其余认 20GB,写错直接被拒绝)与「0 是关闭、不是回退默认」。

变更

  • 标题栏去掉「命令」按钮。 胶囊形入口不再占用标题栏宽度;命令面板仍可从
    「页面 → 命令面板」菜单打开,行为与之前一致。
  • 每个指标格只有一个 owner。 取数口径收进 AppState 的 owner 表
    (decodeReading / averageDecodeReading / prefillReading,输出
    MetricReading/MetricOrigin),曲线、「最近请求」、灵动岛、菜单栏从
    同一组函数取数,数值与角标同源。分工按物理边界:当前速度 owner = 网关
    (引擎只给聚合口径,五家还各不相同);预填充、TTFT 分布、显存、草稿接受
    率、队列、上下文占用、生命周期阶段 owner = 引擎(网关量不到)。引擎
    .live 只在网关没有会话在跑(客户端直连引擎端口)时兜底;网关读数超过
    两拍未刷新同样降级——「过去的现在」不配冒充当前速度。
  • 概览第四格从「内存压力」改为「缓存命中率」。 命中量 / 提示词总量由网关
    按请求打点累加,按 token 加权而不是逐请求平均(一段 100K 上下文命中 95%
    比十次 1K 冷请求更能代表缓存效率);只统计真的收到 usage 的请求,窗口是
    会话表最近 ≤32 条,换引擎 / 换模型 / 引擎重启后从「—」重新等样本。客户端
    绕过网关直连引擎端口时,退回引擎自报的开机以来比值(mlx-serve / MTPLX 的
    cached / prompt 计数器,oMLX 的 total_cached_tokens / total_prompt_tokens)。
    角标只有 AVG;0% 是合法读数(有样本、一次都没命中),「没样本」才画「—」。
    内存占用仍在菜单栏的读数里。
  • hero 只显示模型启动以来平均。 大数字改读网关按会话累计的解码均速:
    分子是生成 token,分母是首 token 到末 token 的解码时长(不含 TTFT、排队、
    空闲),换引擎 / 换模型 / 引擎重启时清零。曲线继续画实时值,两者回答的
    不再混为一谈;没有累计样本时画「—」。
  • 取消 LAST 采集入口。 解码与预填充的当前速度只认 LIVE;预填充保留
    引擎真的累计过的 AVG(文案写明「开机以来均值」),空闲时画「—」,不再把
    上一请求的实测值挂成当前读数。角标只剩「网关」/「引擎实时」与 AVG。
  • 应用内对话的直播条继续走低通。 DecodeRateMeter(τ=2.5s)服务逐分
    片回调的对话页——那边要的是「最后一个脉冲的强度」;概览只在 1 秒节拍上
    读网关,分片不再顺带刷新概览。
  • 模型广场不再展示推荐引擎标签。 结果卡与详情页去掉那枚强调色的引擎名
    (含「无推荐」);量化、已在本机、内存下限、许可与 Hub 标签照旧保留,权重
    归属仍由下载条里的「默认授权给 …」交代。
  • 对话输入框回车发送、⌘回车换行。 SwiftUI 的 TextField(axis: .vertical)
    只会回车换行、没有换行组合键可留,输入框换成 NSTextView 包装
    (UI/ChatComposerField.swift):回车发送、⌘回车换行,输入法组字期间不误发;
    仍按内容长高、封顶 6 行后滚动,聚焦上抬一截的动效与点击聚焦不变。这是应用里
    唯一的按键判定——属于文本编辑而不是全局快捷键;testReturnKeyIsOnlyHandledByComposer
    把 keyDown 覆盖钉在这一个文件里,UI-SPEC「键盘策略」与发送按钮提示同步写明。
  • 应用内取消所有快捷键。 菜单不再带按键等价物;命令面板只响应鼠标点击,
    不再接管方向键、回车或 esc;对话输入框回车换行、发送改为点击按钮;搜索框
    不再回车提交;设置页端口改为点击「应用」;弹窗去掉 .defaultAction。
    设置页与 README 的快捷键说明同步删除。
  • 设置页新增「命令行接口」卡片。 显示开关、控制端口与 flashcat --help
    的复制入口;「恢复默认」会把控制接口恢复为开启、端口 9100。
  • 发版产物。 scripts/build-native-app.sh 同时编译并嵌入 flashcat;
    make-installer.sh 的 .pkg postinstall 创建 /usr/local/bin/flashcat;
    install-app.sh 在 /usr/local/bin 可写时同样链接;make uninstall 会清掉
    指向已安装应用的链接。

修复

  • 切走对话会把正在生成的回答弄丢。 以前切去概览、新建对话或从列表点开
    另一段,都会直接 cancelGeneration(),而它只写 conversation.json——
    「最近对话」里留着的还是上一轮快照,正在流的那条回答既没了、生成也停了。
    现在切走时把整段对话连同它自己的 threadID 搬到后台继续跑,跑完按自己的
    id 落回历史并提示「已在后台生成完成」;开始生成时先把问题写进最近对话,
    列表里立刻有一行可点,点回来就是把后台那份接回前台接着写。侧栏给正在生成
    的那一行标「生成中」;删除或清空对话会先停掉后台那一轮,别让它跑完再写回来。
  • 切页回来对话区是空的。 ChatPage 重建时 ScrollView 报 0 高度,
    scrollTo 按 0 视口算偏移,等高度补齐就落到内容之外。现在先挂一笔「欠一次
    落底」,由 onScrollGeometryChange 量到真实高度再补;超大回答首次布局只量到
    一部分高度,150 ms 后再补一次,读者已经往上翻时不抢回位置。
  • 设置页改「默认模型」不再换掉正在跑的引擎。 这一栏的菜单按引擎分组,
    选别的引擎的模型以前会直接走一次引擎切换:停掉当前引擎、等待进程退出、
    再加载新权重。现在它只是启动偏好:选择记到那台引擎的配置里,当前引擎
    继续服务,行内标注「下次启动」;只有显式切换引擎(或下次启动)才会让默认
    跟着动。引擎存储里的 default 与 active 因此分开,后台的安装/卸载重建
    也不会再把 activeID 挪到默认引擎上。
  • 下载中心的删除按钮发糊。 危险色原来交给玻璃 tint
    (Native.red.opacity(0.55)):tint 是层半透明色雾,红色图标压在同一片红雾
    上,截图取样底色 rgb(185,102,93)、图标 rgb(244,107,94),对比度只有约
    1.4∶1——看上去像失焦。现在危险态不再染玻璃,改成中性玻璃 + 自绘的 12% 红底
    与 0.8 pt 发丝边,图标用满饱和的 Console.danger;边缘由我们画,不经过玻璃
    模糊,深浅色下都清晰。
  • 「最近请求」报出 37 769 tok/s 这种数。 非流式响应(agent 客户端、
    stream: false 的调用)整段正文一口气回来,网关手里只有一个到达点;
    「全程平均」却拿到达窗口的下限 0.35 秒当分母,14 155 token 的回答于是被摊成
    40 443 tok/s,同一批数字还混进了 hero 的「模型启动以来平均」。现在按请求先读
    引擎在响应里自报的 timings(prompt_n / cached_n / prompt_ms 与
    predicted_n / predicted_ms,mlx-serve 在流式末片和非流式正文里都带),
    分子分母都只取引擎真正前向/生成的那一段;没有 timings 的引擎只要没观测到
    真实的到达跨度就画「—」,不再拿窗口下限编一个。单点会话同样不再进累计均值。
  • 预填充速度始终为空(换到 mlx-serve 后又出现)。 根因是这格只认引擎自报的
    预填充字段:MTPLX 在 in_flight[].prefill_state / latest.prefill_tok_s 里给,
    但几百 token 的预填充只要 0.2~0.4 秒,1 Hz 轮询几乎抓不到 LIVE;mlx-serve
    干脆不报预填充速率,于是卡片又整格变空。现在同样以逐请求的实测值为准:
    引擎给了 timings 就用 (prompt_n − cached_n) / prompt_ms(非流式也有),
    没给才退回网关自己的口径——分子是 usage 里的提示词 token 减去
    cached_tokens,分母是请求发出到首 token 的墙钟,且只对流式响应成立。
    前向不足 128 token 的样本一概不报:命中缓存后剩几十个 token 时,耗时由缓存
    恢复的固定开销主导(实测 2195 个 token 里缓存 2164,31 个前向摊 92ms → 334
    tok/s),那个数字既不是算力也不是缓存速度。预填充进行中引擎的 .live 仍然
    优先,其余时间标 LAST(「网关 · 最近一次预填充实测」),引擎的 LAST/AVG
    只在客户端绕过网关直连引擎端口时兜底。AI 服务自己也会报进程级均值,
    prometheusJSON 现在把 generation_tokens_total / decode_time_seconds.sum
    与 prefill_tokens_total / prefill_time_seconds.sum 读成 .lifetimeMean,
    网关一个样本都没有时 hero 与预填充格也能说出「开机以来多快」。
  • Claude 的流式请求只回空正文。 Anthropic 方言翻译出来的上游请求体没有带
    stream: true(只有调用方拿到的 stream 标志),引擎于是按非流式回一整块
    JSON,而转发层是按 data: 行解析 SSE 的——一行都认不出来。Claude Code 这类
    客户端只会收到 message_start / ping / message_stop,正文全空,概览里
    这一路连一个 token 都没有。现在翻译层把 stream 写进上游请求体,流式时再带
    stream_options.include_usage,末片的 usage 才拿得到 completion_tokens 与
    缓存命中量。
  • 组字中的输入被自动清掉。 输入框原来拿 textView.string 直接跟草稿
    Binding 比:输入法组字的 marked text 已经在文本视图里、却还没进 Binding,
    任何一次视图刷新(每秒指标、焦点变化)一比就把没确认的拼音回写成空串。现在
    只在「视图没有未回报的编辑」且「草稿确实被外部改写」时才回写,组字期间一律
    不碰,等提交后由 textDidChange 对齐;也不再由草稿状态反向抢第一响应者——
    组字中途被夺焦同样会丢候选。同一份源码跑了对照组:旧逻辑属性一更新就是
    marked=false 视图="",新逻辑保持 marked=true 视图="zhong" 直到提交。
  • 背景的透明度与模糊「拖一个条,另一个条的改动才生效」。 窗口表面
    (isOpaque / 底色)和毛玻璃层的强度都只在 DesktopBackdrop.updateNSView
    里更新,而这个 representable 的入参只有 blur:只拖 APP 透明度时它一次
    都不会被回调,窗口仍是不透明的,桌面根本不露出来;等到下次拖模糊,才连带
    把上一步的透明度一起落下去。现在改由 BackgroundSettings 的 didSet 直接
    驱动 BackgroundSurface,参数一变窗口和毛玻璃层立刻跟上,不再依赖任何视图
    的更新时机;透明度为 0、又没有背景图时把模糊滑杆禁用并说明原因,不再留一根
    按了没反应的滑杆。
  • 图片模式的透明度后半程没有变化。 保底渐变原来写死
    max(1 - opacity, floor),深色下超过 58% 之后整段都停在 0.42,滑杆最后
    近一半行程是空的;现在把剩余行程线性铺到保底值上,两端数值不变
    (BackgroundMath.veilOpacity)。
  • 概览解码速度闪烁。 根因不在引擎上报,在我们自己的打点:每个 SSE
    分片喂一个脉冲进连续时间低通,逐次读取。低通的输出随取样时刻连续
    衰减(τ=2.5s 下 0.5s 静默就掉 18%),秒拍与预填充期的 0.4s 快拍各读
    各的,衰减的谷值紧跟着下一个分片的加热峰值——谷—峰交替正是「忽高忽低」
    的本体;分片成批到达(SSE 抖动、MTP/DFlash2 一次验证多个 draft token、
    下游消费慢时 TCP 背压把上游憋成脉冲串)时更严重。新口径是墙钟窗口:
    DecodeWindowMeter.rate(at:) = 窗 [t−W, t] 的量 ÷ 已观测跨度,分子
    分母一起滑,稳态恒等于吞吐,与分片大小、到达分布、轮询相位全部无关;
    边缘压着的分片按「铺在自己的到达时刻上」部分计。窗口右缘钳到最后一个
    事件——秒拍与快拍共用同一个读数也不会错开,早读几十毫秒不会把窗口
    掏空成 0。
  • 收尾后曲线冻结,不再挂 LAST。 GatewayMeter.overview 只把没收尾的
    会话算作 isLive;finish 一落下,当前速度归零、60 秒曲线的右缘冻结在
    那一刻(throughputFrozenAt),不再随挂钟把终点挤出窗口。上一请求的终值
    不再冒充当前速度,也不进曲线;新请求开始后自动解冻。
  • 总解码曲线按 1 秒一拍。 概览不再被 SSE 分片或预填充 chunk 推着
    「立即变化」:引擎轮询统一 1 秒,曲线每拍最多落一个点(≥0.9s 的抖动
    余量),静默段不拿 0 填谷。请求收尾停住整张图;横轴上 1~2 个样本的
    短请求改画点标记,不再被当成空图。
  • 首字时刻不再漏记 role-only 分片。 addTokens 的记账顺序修正:旧
    实现先 guard count > 0 再记 firstTokenAt,空 delta(role-only 首帧、
    finish_reason 帧)整帧忽略——TTFT 被记晚、预填充读数随之偏低。现在
    「流开始回东西」的第一帧就记下(0 token 只记时、不计生成量)。
  • 灵动岛与概览同口径。 胶囊以前引擎 LIVE 计数优先、再落应用内这一路
    的本地测速,与概览 hero 的取数顺序相反,两处数字天然对不上;现在统一
    走 owner 表,只认 LIVE(网关 或 引擎实时),绝不回落 LAST/AVG。

命令行与控制接口

  • 退出改为同步收尾。 applicationShouldTerminate 不再返回 .terminateLater 后靠
    一个 Task 去回信:当前 macOS 会在任务被调度前销毁进程,导致引擎仍驻留、最后
    一次历史写盘丢失。现在在委托里同步走完网关/引擎/下载收尾,最坏等待仍被 1.5 秒
    的引擎宽限期封顶;flashcat app quit 因此能真正等到进程消失并清掉 control.json。
  • 概览保留最后一次请求。 GatewayMeter 不再在结束 6 秒后删除会话:
    「最近请求」保留完成 / 失败行(最多显示 6 条,底层保留 32 条),直到被后续
    请求挤出列表。已结束行的耗时固定在收尾时刻,不会跟着挂钟继续涨;它的全程
    均值只留在行内与累计平均里,当前速度与曲线在收尾时归零 / 冻结,不再挂
    「网关 LAST」。
  • 命令行不再误删版本、也不再误判终端。 engines uninstall omlx@0.7.2 在只装了
    0.7.3 时报错,而不是确认后删掉 0.7.3;chat - 与 --yes 确认改看 stdin 是否
    终端,echo … | flashcat chat - 在终端里也能用;重复 --for 累加而不是只留
    最后一个;表格按 CJK 显示宽度对齐;--control-url 只接受回环地址或 HTTPS,
    不把控制令牌明文发给网络;logs --app --level 与服务端日志过滤口径一致;
    control.json 从创建起就是 0600,不再有"先 0644 再 chmod"的窗口。
  • 控制接口启停竞态。 关闭开关时,正在绑定端口的启动会被作废并关掉新监听,
    不会在设置关闭后留下一个还能驱动应用的接口。
  • flashcat engines start 报「未能就绪:等待超时」,引擎其实已经起来。
    startService() 把启动丢进一个 Task,控制器要到下一次 actor 跳转才进
    .starting;等待方第一眼看到的还是 .stopped,旧实现直接判失败。现在
    .stopped 在 5 秒宽限期内不算失败,见过 .starting 之后再停才是真的停了。

MTPLX 的近前缀恢复

  • GDN boundary 撑爆条目。 MTPLX 的 session bank 预算有 1 GiB 下限,而一条
    19K token 的条目光 GDN boundary 记录就要 700 MB 以上(每条 90 MB、默认最多
    8 条),put() 把这份开销计入条目大小后整条拒绝,bank 里只剩不含
    boundary 的条目;recurrent_boundary_at_or_below() 对这类条目返回 None,
    近前缀恢复每次都被判 boundary_not_better 淘汰,最终报成 ssd_prefix_miss
    ——把 adm...
Read more

flashCat 1.5.3 · 实时 · 可比 · 轻量

Choose a tag to compare

@imi4u36d imi4u36d released this 08 Nov 09:16
3df9351

flashCat 1.5.3 · 实时 · 可比 · 轻量

把概览的速度读数收成一套口径:解码统一走网关,引擎只保留自己真正量过的生命体征;
同时去掉装饰数据,把采样内存收口。

修复

  • 预填充那格不再挂着一个恒定不变的大数字。 过去把引擎的「上一请求终值」或
    「开机以来均值」当成当前速度:splash 的 prefill_tokens_per_second 是两个累计
    计数器之比;MTPLX 的 latest.prefill_tok_s 只在请求结束时落一次,空闲时原样重复。
    现在按粒度打 LIVE / LAST / AVG 角标,卡片说明随之改口,空闲时不再冒充当前速度。
  • splash 改用真·瞬时批次值。 current_prefill_batch / current_decode_batch
    带 valid 标记;有样本时标 LIVE,刚启动没跑过同类批次时退回均值并标 AVG。
    同时按 active_requests[].phase 区分「正在跑」与「上一批残留」。
  • MTPLX 接上正在预填充的那一路。 实时值在 in_flight[].prefill_state,服务端
    每完成一个 chunk 就刷新;多路并发取 elapsed_s 最大的那一路,和 MTPLX 自己的
    仪表盘同口径。兜底从单 chunk 峰值换成 tokens / compute_time_s 滚动均值,峰值只留诊断。
  • EngineLiveRates 的闩锁降级为 LAST。 值仍然保留,卡片不会空成「—」,但粒度
    如实标成「上一个请求的实测值」;真有 prefill_tokens_live 在涨时才回到 LIVE。
  • isLive 布尔换成 EngineRateKind。 一个 bool 分不出「上一请求」和「累计均值」;
    多端点合并时粒度与数值同源,取 rank 最高的那一路,不会出现「数值是均值、角标写 LIVE」。
  • 预填充不再回落到网关估算。 网关的 (整段提示词 − 缓存命中) / TTFT 分母混着排队
    与缓存恢复,分子要等末帧 usage,请求进行中算不出可靠值;引擎不上报时显示「—」。

变更

  • 概览解码速度统一走网关。 hero 大数字、总解码曲线与「最近请求」改为同一份按请求
    低通聚合:大数字 = 活跃会话速率之和,三处数字能对上;「最近请求」明确标「网关估算」。
    引擎的 LAST / AVG 不再参与当前速度;只有网关没有在跑会话(客户端直连引擎端口)时
    才用引擎实时计数兜底,且要求 activeRequests > 0。
  • 来源和值一起显示。 hero 角标区分「网关估算 / 网关 LAST / 引擎实时」;曲线 chip
    同样标来源;没有实时值显示「—」,不再拿 0.00 冒充读数。
  • SESSIONS 改读引擎 activeRequests。 直连引擎端口的请求也会算进去;预填充、
    首字 p50、内存与上下文上限继续读引擎,说明文字标明「引擎」。
  • 总解码曲线横轴固定 60 秒。 Swift Charts 默认按样本时间范围铺满宽度,只有两三个
    样本时会把一次 1 秒的请求拉成一整条长线;现在短线只占右侧那 1 秒。
  • 去掉三张指标卡写死的装饰迷你柱。 上下文卡生成中标 EST,结束后回落到引擎 usage。
  • 预填充读数改成「最近一小段」的实时值。 只保留最近约 1.2 秒(1~2 个 chunk)的
    采样点;chunk 之间保持上一格的实测速度,超过 3 秒没有新 chunk 才退回本轮累计均值。
    预填充期间轮询提到 0.4 秒,跟得上 chunk 节奏;其余时间仍是 1 秒。

性能

  • 概览采样内存收口。 曲线只服务 60 秒 / 5 分钟,样本保留从 30 分钟降到 10 分钟;
    ThroughputSample 不再为每个点分配 UUID;网关快照从 [String: Any] 改成结构体,
    每秒刷新少了字典装箱与字符串键;删掉每会话 480 格、但没有任何界面在读的历史桶。

工程

  • 本版 258 个单元测试通过(44 个 App + 214 个 Kit),3 个依赖本机运行时包 / 集成环境
    的用例自动跳过。
  • pack-index.json 收录 MTPLX 2.12.3。
  • EngineLiveRates、StatusParser、GatewayMeter 的回归用例覆盖了 LIVE / LAST / AVG
    三态、末帧 usage 不回灌速率、多路速率相加等边界。

安装

  • flashCat-1.5.3.dmg:打开后把 flashCat 拖进「应用程序」
  • flashCat-1.5.3.pkg:双击一路安装

系统要求:Apple Silicon,macOS 26.0 或更高(splash 引擎自身要求 26.4)。
应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。
引擎运行时不包含在应用内,首次启动按引导下载(80 MB ~ 600 MB)。

flashCat 1.5.2 · 优雅 · 流畅 · 高能

Choose a tag to compare

@imi4u36d imi4u36d released this 06 Nov 13:53
f0a9ae0

flashCat 1.5.2 · 优雅 · 流畅 · 高能

把「谁在跑哪个模型」这件事做对:网关按请求里的 model 准备权重,界面能透出桌面,
忙等的时间开始说真话。

新增

  • 网关按 model 路由并拉起模型。 请求里的模型名不再只是装饰字段:网关先解析它属于哪台引擎,
    同引擎换权重走热切换 / 重启,跨引擎先卸载再启动,引擎没跑就把它拉起来,就绪后才向上游转发。
    以前把未知模型名原样交给「忽略 model 字段」的引擎,客户端会拿到错误模型的成功响应——
    这比报错更糟。并发 API 请求在网关侧串行准备,不会两次 load 抢同一个单飞位。
  • 自定义背景。 设置里可选一张图片作为画布背景,带「APP 透明度」与「背景模糊」两档:
    图片会复制进应用支持目录,原图移动或删除后仍然可用;无论图片多清晰都保留一层画布渐变保底,
    文字对比度不塌。没设图片时透明度控制透出桌面——窗口按同一档强度让位给系统壁纸。
  • 图标换脸。 应用图标重画为宽脸颊、尖耳朵、额头一道闪电负形的猫头;菜单栏图标改用
    手绘贝塞尔剪影 + 模板渲染(运行中实心、停止描边),由系统按菜单栏明暗自动上色,
    缩到 18pt 不再是一坨彩色小色块。五台引擎与 splash 启动图各配一枚品牌图标。
  • 命令面板新增「切换外观」与「折叠 / 展开边栏」;⌘K、⌘N、⌘\、⌘⇧A 回到菜单与标题栏提示同源。

修复

  • 应用最低系统版本回落到 macOS 26.0。 macOS 27 的 .tabs 分段样式改为可用性探测,
    运行时不可用时回退 .segmented;Info.plist、README、CONTRIBUTING、architecture.md
    与 Package.swift 五处门槛一次对齐。splash 引擎自身仍要 26.4,那是引擎级要求。
  • 加载权重的等待时间不再虚报。 热加载引擎的 HTTP 壳子先绿、权重后到,
    这段等待此前按进程启动时间计算——引擎跑了几小时后重载模型,界面会报「已等待 4:12:03」。
    现在加载阶段单独计时,且从点下启动那一刻起表。
  • 切换模型时误杀自己。 sh -c script name a b c 把 name 交给 $0 而不是 $1;
    缺占位参数时脚本把应用的 pid 当成引擎,引擎一起来就 SIGINT 了 flashCat 自己。
  • 预填充读数虚高两个数量级。 同一会话的第二轮几乎全部命中引擎的前缀缓存,
    这些 token 根本没被重新前向。现在从 usage 的 cached_tokens 扣掉命中量,
    全命中时回落到引擎实时计数;几路并发改为各路速率相加。
  • agent 会话一直显示 0 tok/s。 工具调用的回复大头在 delta.tool_calls[*].function.arguments,
    而打点只读了 delta.content;现在正文、思考、工具调用名与参数一起计入生成量。
  • 切壁纸后玻璃层留残影。 画布回到不透明底色承载,桌面透出交给全窗口的视觉效果层,
    并监听壁纸变更强制重排一次。
  • 下载列表不再因重复 id 出现空位;灵动岛收起态只留标题与一行信息;
    通知缺标题时按级别兜底命名;旧的推理等级取值在读取时收敛到新范围两端。

性能

  • 模型目录扫描加 1 秒 TTL(下载 / 删除 / 重载时立即失效),下载进度刷新不再反复扫盘。
  • 网关复用同一个 URLSession,不再每请求建销连接池。
  • 空闲时隔秒轮询,忙起来恢复每秒;健康探测响应复用给遥测采集,各端点并发拉取。
  • 日志页一次遍历同时得出按级别计数与过滤结果;Markdown 解析分两级缓存;
    概览图表按 60 秒窗口取数,不再每秒把约 3600 个样本交给 Swift Charts。
  • 对话高频状态拆成独立的 ChatStore,流式分片不再带着概览与模型页一起重算;
    长对话只渲染最近若干条。

工程

  • strict-concurrency 棘轮基线 36 → 25;ci.yml 说明随之更新。
  • 新增 GatewayModelRoutingTests、GatewayMeterTests、EngineLiveRatesTests、
    ModelFamilyTests、ModelLibraryTests、DecodeRateTotalTests,以及 LocalizationTests
    三条契约(每条中文词条都有英文译文;快捷键文案与 keyboardShortcut 同源;
    界面文案在两种语言下都能解析)。
  • pack-index.json 收录 splash 1.6.0、mlx-serve 26.11.2、strata 0.2.11、omlx 0.7.3rc1。
  • 本版 201 个单元测试,0 失败,3 个依赖本机运行时包 / 集成环境的用例自动跳过。

安装

  • flashCat-1.5.2.dmg:打开后把 flashCat 拖进「应用程序」
  • flashCat-1.5.2.pkg:双击一路安装

系统要求:Apple Silicon,macOS 26.0 或更高(splash 引擎自身要求 26.4)。
应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。
引擎运行时不包含在应用内,首次启动按引导下载(80 MB ~ 600 MB)。

flashCat 1.5.1 · 优雅 · 流畅 · 高能

Choose a tag to compare

@imi4u36d imi4u36d released this 05 Nov 11:22
3b539cc

flashCat 1.5.1 · 优雅 · 流畅 · 高能

界面开始说两种语言,模型卡开始标量化。

▶ 观看 1.5.1 介绍片(50 秒,无旁白,1920×1080)

新增

  • 中英双语界面。 全部界面文案收敛到 Localizable.xcstrings(435 条,简体中文为源语言、英文全覆盖),
    跟随系统语言切换;菜单、弹窗、灵动岛、模型卡、引擎页、日志、toast 都走同一套 L10n。
    Info.plist 声明 zh-Hans / en,构建时把 SwiftPM 资源包里的 .lproj 一并镜像进 app 的 Resources,
    打包版与 swift run 都能取到词条。
  • 模型量化标识。 模型卡新增 QUANT 一行:从文件名、仓库 id、assembly 的 files 与权重 config.json
    识别 GGUF(Q4_K_M / IQ3_S / Q2_0)、MLX(oQ4e / 3 bpw)、8-bit、BF16 / FP16,
    公共目录里的共享权重同样标出。量化不用再从仓库名里猜。
  • 模型卡标签去掉与 QUANT 重复的量词,避免同一个标签印两遍。

修复

  • 灵动岛的通知分级改为在本地化之前按源文案判断,英文界面下 “failed / switching” 一类消息
    也会归到错误 / 警告,而不是一律信息。
  • 格式化文案改用 L10n.format,插值后的字符串不再绕过翻译。

工程

  • 新增 LocalizationTests(两种语言都随包发出、核心词条有英文、中文回退到源文案)
    与 ModelQuantizationTests(GGUF / MLX / bit / 无量化名)。
  • CFBundleDevelopmentRegion 由 zh_CN 改为 zh-Hans,补 CFBundleLocalizations。
  • README 重写「亮点」与宗旨,补上介绍视频。

安装

  • flashCat-1.5.1.dmg:打开后把 flashCat 拖进「应用程序」
  • flashCat-1.5.1.pkg:双击一路安装

系统要求:Apple Silicon,macOS 27.0 或更高。应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。
引擎运行时不包含在应用内,首次启动按引导下载(80 MB ~ 600 MB)。

本版 209 个单元测试,0 失败,3 个依赖本机运行时包 / 集成环境的用例自动跳过。

flashCat 1.5.0

Choose a tag to compare

@imi4u36d imi4u36d released this 05 Nov 10:04

flashCat 1.5.0

首个纯原生界面的版本:界面从 WebView 换成 SwiftUI / AppKit,视觉改为 macOS 26 Liquid Glass,
并按引擎的真实生命周期(启动 → 加载权重 → 就绪)来描述状态。

新增

  • 灵动岛通知中心。 标题栏中央常驻玻璃胶囊:平时是引擎状态(引擎名、真实阶段、实时 tok/s、启停)。
    所有 toast 改从灵动岛弹出,按文案归为信息 / 成功 / 警告 / 错误四类,保留本次会话的通知历史与未读数
    (最多 30 条,3.2 秒后自动回到引擎状态)。点开原位展开:有通知时是通知列表(相对时间、清空),
    没有通知时是引擎详情(模型、状态、接口、版本、实时速度),点胶囊外任意位置收起。
  • 反馈与交流。 侧栏新增入口,弹窗展示 QQ 群号,可一键复制、拉起 QQ;群号留空时显示「待配置」。
  • 模型家族识别。 新增 ModelFamily,按仓库 id、标签与提示词认出 Qwen、DeepSeek、Llama、Mistral、Gemma、
    Phi、GPT、Nemotron、Granite、GLM、Kimi、Flux、Liquid、MiniMax 等家族,广场列表、详情与模型卡统一显示家族徽标。
  • 模型卡渲染。 模型详情把 Hugging Face README 清洗(去 front-matter、徽章与 HTML 标签、还原实体)后
    交给 Markdown 渲染,不再是满屏尖括号。
  • 日志详情。 日志行可点击展开完整正文,附完整时间、字符数与单行复制;行内改为级别色圆点 + 胶囊标签。
  • 引擎生命周期状态。 启动、卸载 / 加载权重、预热、等内存期间,标题栏、概览、菜单栏、引擎页显示真实阶段
    与「已等待 m:ss」;权重真正就位才显示「运行中」并允许对话。
  • 引擎状态细分。 引擎页区分运行中 / 启动中 / 停止中 / 异常,不再把加载权重误报成「已停止」。
  • 模型切换进度。 模型菜单里正在切换的那一项显示转圈与阶段文案(启动引擎 / 停止旧引擎 / 加载权重…)。
  • 对话计入网关统计。 应用内对话直连引擎端口时也向网关打点,概览「最近请求」与会话网格不再永远是 0 条。
  • 下载中心。 进行中的任务只保留顶部一行,状态标签区分下载中 / 已暂停 / 失败。

界面与交互

  • 界面回到纯原生。 六个页面、启动页、下载中心、模型广场、引擎配置与对话参数全部是 SwiftUI / AppKit 视图,
    直接读写 AppState:没有 WKWebView、没有快照桥、没有 token 级 IPC。删除 WebView 壳与整个 WebUI/
    (14 个 ES module + 8 份 CSS + bundle,约 2.8 万行)及 esbuild 工具链。
  • 版式逐页对齐原 WebUI:200 pt 玻璃侧栏、浮层标题栏、概览(hero + 网关 + 四指标 + 总解码 / 最近请求)、
    模型(引擎分段 + 搜索 + 两列大卡)、引擎(运行时统计 + 整行卡片)、日志(过滤条 + 玻璃控制台)、设置(左右两列)。
  • 窗口 chrome:48 pt 标题栏(折叠边栏、⌘K、外观切换、下载中心徽标)、可拖动调宽侧栏(180–320 pt)、页面切换淡入;
    标题栏不再重复放引擎胶囊,红绿灯整体右下挪 6 pt,侧栏收起档 76 → 96 pt。
  • ⌘K 命令面板:六页跳转、启停引擎、新对话、生成参数、下载中心、模型广场、切换外观、折叠边栏;↑↓ / ↵ / esc。
  • 对话:回车发送、⇧回车换行、滚动离底「回到最新」、思考块流式展开 / 首字后折叠、生成光标与呼吸点;
    输入框由 TextEditor 换成可纵向生长的 TextField(没有自带滚动条,点一下就能聚焦);
    思考菜单只列当前引擎提供的等级并勾选。
  • 模型与引擎:卡片 hover 抬升、当前项强调色描边;「正在使用」状态替代禁用按钮;模型广场支持手填 owner/repo 预检。
  • 启动页:与控制台同一套玻璃语言与画布,逐项进场动画,已安装改为玻璃徽标,安装进度显示当前步骤。

优化与变更

  • 最低系统版本提高到 macOS 27.0。 按钮组使用 macOS 27 的 .tabs 分段控件(Liquid Glass),应用下限随之上移;
    splash 引擎自身的 26.4 下限已在这个门槛之下。
  • Liquid Glass。 自绘的渐变卡片、顶部高光与冷色投影换成 macOS 26 glassEffect;窗口改为透明、内容区自铺画布,
    侧栏与标题栏成为能采到桌面的真玻璃。按钮、卡片、菜单与浮层统一走这一层材质。
  • 互斥按钮组改用 macOS 27 原生分段控件(.tabs):模型页引擎切换、日志级别过滤、设置页外观 / 思考模式 / 思考等级。
  • 所有 .plain 按钮换成 plainHit:整块玻璃底与内边距都算命中区,不再必须点到字形。
  • 切换模型的确认文案精简为「将停止 X 并加载 Y,切换期间引擎暂时无法应答」。
  • 动效统一到 Motion(140 / 220 ms + 轻弹簧)并服从 reduce-motion;持久化深色外观在启动时即时生效。
  • 安装脚本不再把上一版留在 /Applications:备份移出系统目录并注销 LaunchServices 记录,避免旧构建被 Spotlight / Dock 打开。

修复

  • 热切换期间引擎已报 ready、权重却还在搬:健康探测失败会让「已等待」停住,现在继续每秒刷新。
  • 应用内对话不进网关统计,概览「最近请求」永远 0 条。
  • 下载中心进行中的任务同时出现在顶部与列表,看起来像两个下载。
  • 删除正在下载的任务时只暂停、留下半成品与任务行;现在真正清理。
  • 启动 / 加载权重窗口内仍可发送对话、报错后才提示;现在直接给「模型正在…,请稍候」。
  • 旧进程的退出回调不再打断新进程;停止引擎时会真正回收忽略 SIGINT 的子进程。
  • 引擎启动增加就绪超时,不再永久停在「启动中」;退出应用改为异步收尾并清理全部引擎。
  • 快照序列化失败不再静默;note() 不再关闭运行期日志写入句柄。
  • 流式回复改为按消息 id 写入,切换会话不再污染另一条会话。
  • 安装脚本失败不再导致 /Applications 里没有应用(失败回滚)。

安装

  • flashCat-1.5.0.dmg:打开后把 flashCat 拖进「应用程序」
  • flashCat-1.5.0.pkg:双击一路安装

系统要求:Apple Silicon,macOS 27.0 或更高。应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。
引擎运行时不包含在应用内,首次启动按引导下载(80 MB ~ 600 MB)。

本版 202 个单元测试通过,3 个依赖本机运行时包 / 集成环境的用例自动跳过。

flashCat 1.4.2

Choose a tag to compare

@imi4u36d imi4u36d released this 03 Nov 04:15
161e1f3

flashCat 1.4.2

这一版补齐了模型管理与首次使用体验,同时重做了 WebUI 的控件、图标和交互动效。

模型广场与共享目录

  • 模型页可以直接搜索 Hugging Face,结果按仓库卡片展示,并支持选择 GGUF 量化。
  • 下载到公共模型目录,只保留一份权重;勾选引擎后通过符号链接让它出现在对应引擎的模型目录,不复制文件。
  • 已下载但不在内置目录里的权重也会进入模型库,并标为「未收录」;删除正在运行的模型前会先停止引擎。
  • 内置目录改用引擎标签归属,不再维护第二套列表。

硬件推荐

  • 首次启动根据本机内存与可用磁盘,为 Splash、oMLX、MTPLX 各推荐一档最适合的模型。
  • 引擎安装完成后自动下载推荐模型;Splash 会同时准备对应的 DFlash2 draft,缺失时在启动前补齐。
  • oMLX 主推三档 Jundot oQ4e 包;MTPLX 主推三档 Qwen,并额外收录 MiMo 9B 与 Qwen3.5 4B 优化包。额外收录项不参与硬件三档评选。

界面与交互

  • 统一使用本地 Lucide 图标集,导航、按钮、菜单、状态与空状态采用一致的图形语言和描边。
  • 重做按钮、筛选、分段控件、焦点态与按压反馈;可点击的 DIV/SPAN 控件补齐键盘操作与语义。
  • 侧栏折叠动画、宽度与手柄移动统一;概览指标顺序调整为解码、预填充、首字延迟、内存。
  • 弹层更新改为局部 morph,不再重播入场动画,并保留滚动位置、输入焦点和光标。
  • 菜单支持 Escape 关闭,Toast 与状态提示补齐无障碍属性。

修复

  • 根目录的拆分 GGUF 不再被误判成一档量化。
  • Hub 搜索推送可以正常重绘,量化下拉不再丢失监听。
  • 引擎包索引使用相对下载地址,重定向后仍能正确解析。
  • 应用最低系统版本统一为 macOS 26.4。

安装

  • flashCat-1.4.2.dmg:打开后拖进「应用程序」
  • flashCat-1.4.2.pkg:双击一路安装

应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。运行时包不包含在应用内,首次启动按引导安装。

本版 164 个单元测试通过,3 个依赖本地运行时包或集成包环境的测试自动跳过。

flashCat 1.4.1

Choose a tag to compare

@imi4u36d imi4u36d released this 31 Oct 14:37
13e2bc9

flashCat 1.4.1

这一版修的是模型切换的可靠性:跨引擎切换进行中再选一个模型,界面会永久停在「切换中」,只能重启应用。

修复:跨引擎连续切换卡在「切换中」

以 22:02 那次事故为样本,三个漏洞叠在一起:

  • 切换完成判得太早:oMLX 的 uvicorn 在权重还没搬完时就返回 application startup complete(/health 立刻 200),而 103GB 权重要到下一秒才开始 Loading model。旧逻辑只等健康检查,于是把一次 27B 的加载在开头就判成完成——4 秒后再点一个模型,那台还在搬权重的进程直接吃 SIGINT,要等 20 秒强杀才让出显存。现在切换的就绪判据是「目标模型真的进了引擎自己的 loaded_models」。
  • 第二次选择被静默丢弃:useModel / applyModelFromAnyEngine / applyModel 开头都是 guard !isSwitchingModel else { return },换引擎只 toast 一句就返回,点了等于没点。现在跨引擎的新选择立刻接管上一次切换,同引擎的二次选择排队(只保留最后一次),切换中换引擎也不再被拒绝。
  • 旧切换任务没人收尾:被跳过的任务走 guard !Task.isCancelled else { return } 直接返回,switchingModel 永远留着。现在切换状态带代数(generation),被接管/被取消的旧任务静默退出,没有任何路径能把界面留在「切换中」。

生命周期提示补全

「切换中」不再是一句冻结的文案:

  • 概览、侧栏、菜单栏一并显示 切换中 · <阶段> · 已等待 m:ss,热引擎权重还在搬时按「加载权重」报阶段而不是「就绪」
  • 切换中提供取消等待按钮:放弃等待,引擎继续在后台加载,状态交回引擎自己的启动阶段(进度、秒数、日志继续走),不会打断搬了一半的权重

附带的概览页改动

  • 新增会话网格:网关侧按请求打点,一格一路请求,显示解码/预填充速度、首字延迟、输入 token、上下文占用与该路的速度曲线
  • 并发口径标注:多路并跑时「解码速度」是引擎聚合值,标签会说明,不再统一标 LIVE
  • MTPLX 标注「仅支持串行」并说明并发会排队
  • 吞吐曲线保留窗口 5 分钟 → 30 分钟,「全部」档不再等于「5 分钟」

安装

  • flashCat-1.4.1.dmg:打开拖进「应用程序」
  • flashCat-1.4.1.pkg:双击一路安装

应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。运行时包不含在应用内,首次启动按引导安装。本版 116 个单元测试全部通过。

flashCat 1.4.0

Choose a tag to compare

@imi4u36d imi4u36d released this 31 Oct 09:43
b830379

flashCat 1.4.0

集中在两件事:把 WebUI 的实时指标与列表页从"整页重绘"改成"就地更新",以及菜单栏面板与引擎启动流程的重做。

性能(实测对比,M3 Max / 120Hz 屏)

  • 主线程不再同步扫模型目录:EngineModelStore 加 20s TTL 缓存,下载完成/卸载模型时失效。概览页空闲 CPU 20.7% → 约 6%,主线程 pushSnapshot 采样从 12 秒内 2067 样本降到 258
  • 六页渲染改为 keyed DOM morph(data-key/data-log 对齐,输入框内容不再被覆盖):对话页 300 条历史 38ms → 12ms(掉帧 7 → 0)、10Hz 流式 6ms → 3ms、日志页 1Hz 新行 25ms → 4ms(掉帧 4 → 0)、概览页 1Hz/10Hz 4ms/3ms → 2ms
  • 动画不再被重绘打断:流式期间转圈动画重启次数 57 → 1
  • 日志控制台改增量追加(新行插入 + 尾部裁剪),单次推送 DOM 增删 30 → 0
  • 事件监听幂等化(bindOnce),修复节点复用后"点一下等于点两下"的隐患

新增与改进

  • 菜单栏面板重做,新增状态栏控制器
  • 引擎启动阶段(EngineStartupStage)独立建模,带单元测试(116 个测试全部通过)
  • 图标、README、设计系统细节更新

关于 120Hz

WebKit 在 macOS 会把 WKWebView 的渲染上限压在 60Hz(_displayLinkWantsHighFrameRate 恒为 false,无可用 SPI;连 CSS 合成动画也一样)。屏幕是 120Hz 的话,这一层是平台限制,只有原生渲染能突破——已单独规划,不在本版本内。

安装

  • flashCat-1.4.0.dmg:打开拖进「应用程序」
  • flashCat-1.4.0.pkg:双击一路安装

应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。运行时包不含在应用内,首次启动按引导安装。

flashCat 1.3.0

Choose a tag to compare

@imi4u36d imi4u36d released this 30 Oct 05:55
a899007

flashCat 1.3.0

UI 层整体重写为 WKWebView 混合壳:设计稿 1:1 网页渲染,Swift 引擎管线不变。

新界面

  • 六页(概览/对话/模型/引擎/日志/设置)+ 启动页全部按「精密仪器」设计稿 1:1 重做,日/夜双皮肤
  • 启动页、下载中心、引擎配置、对话参数全部在网页层完成,原生弹层下线

性能

  • 菜单切换提速:乐观导航(点击即切)+ 快照去重跳过空转重绘 + 推送链路压缩
  • 日志序列化复用 formatter,心跳空转不再整页重绘

修复

  • 启动页塌陷成窄条(网格布局回退)
  • 模型/日志搜索框每敲一个字丢焦点
  • 对话页实时速率/耗时芯片不更新;流式输出期间上翻阅读不再被拽回底部
  • 中文输入法组合期间不再被重绘打断

安装

  • flashCat-1.3.0.dmg:打开拖进「应用程序」
  • flashCat-1.3.0.pkg:双击一路安装

应用为 ad-hoc 签名、未公证,首次打开请右键 → 打开。运行时包不含在应用内,首次启动按引导安装。

flashCat 1.2.0

Choose a tag to compare

@imi4u36d imi4u36d released this 30 Oct 02:59
3bf860d

新特性

  • API 网关(OpenAI + Claude 双格式):内置本地网关默认 http://127.0.0.1:9000/v1,同时提供 OpenAI(/v1/chat/completions)与 Claude(/v1/messages)标准格式与统一模型列表(/v1/models),支持流式输出、工具调用、图片输入;请求自动转发到当前运行中的引擎,引擎切换/换端口都不用改客户端配置。设置页可开关与改端口。
  • 菜单栏常驻面板:菜单栏图标实时显示服务状态,点开可看当前模型、解码速率、首字延迟、内存占用,支持启停服务、复制接口地址;关闭主窗口后应用留在菜单栏继续对外服务。
  • 模型下载中心:下载任务持久化,支持暂停/继续(断点续传)/取消/重试,显示字节级进度与速度;按本机芯片/内存/磁盘给出模型适配提示与推荐排序。
  • 引擎进程治理:退出时整树终止引擎防孤儿进程,启动时自动清扫残留,全引擎接入 detached watchdog(应用崩溃后也能收干净引擎进程)。

改进

  • 引擎安装进度改为环形百分比 + 步骤文案,成功/失败弹气泡提示
  • 引擎卡片与启动页布局精简;模型库、对话页、概览页、设置页大量视觉与交互打磨
  • 上游引擎运行时包构建摆脱 Homebrew 依赖(自举 uv + 上游 wheel 校验下载)

修复

  • 对话页 tok/s 偶发虚高、模型卡大小统计错误(符号链接)
  • 模型下载进度条不动(tqdm \r 解析、字节级目录监控、半成品目录误判)
  • 引擎未安装时切换模型假成功、启动中途退出应用导致引擎进程残留

安装包为 ad-hoc 签名、未公证:首次打开请在 Finder 里右键 flashCat → 打开。

应用不含推理引擎,请自行构建引擎运行时包或把 FLASHCAT_PACK_INDEX_URL 指向你自己的索引,见 README。