Skip to content

PI 0.1.5(pi 1.3.0)· 订阅登录与界面重做

Choose a tag to compare

@heikeyangle-code heikeyangle-code released this 31 Oct 18:45

引擎:@earendil-works/pi-coding-agent 1.3.0(与上一包相同,不含引擎升级)。

从 v0.1.4 到这里共 153 笔提交。这一版是新功能 + 整体界面重做:订阅登录、配色方案、悬浮输入框、模型能力编辑、思源宋体、拆底栏、排版重定标。


新功能

订阅登录:原生 OAuth,不经过终端

以前登录订阅账号要开终端敲 pi /login。现在模型与供应商屏顶部有一张「订阅账号」卡,点进去就是完整的登录流程:

  • 清单不硬编码:直接取 pi 的 builtinProviders() 过滤 auth.oauth,pi 认几家就有几家
  • 登录就是 pi 自己的登录:调同一个 pi-ai 的 auth.oauth.login(interaction),auth_url / device_code / progress 通知直通界面
  • 按 pi 的提示画界面:设备码、浏览器链接、select / text / manual_code 四种交互全支持;粘贴整条回调地址的入口一直可见
  • 写盘走 pi 自己的规矩:PiAuthStorage.setOAuth —— 锁、0600、镜像目录、等重启标记;只校验 pi 会拒绝的那几条,其余键(accountId / enterpriseUrl / scope)原样保留
  • 失败会说话:providers() 加 20 秒超时,进程 stderr 留最后 40 行带进错误;读不到时用内置九家清单撑起页面并标明「运行时没响应」,可以重试

从订阅登进来的厂商不再显示「换 Key / 改模型」——Key 与模型清单都不是人填的,只剩「删除」。

配色方案 / 系统主题

pi 的 system 主题本来就是按调色板推导出全部 56 个 token 的。现在这个推导搬到了手机上,调色板由你选:

  • 四档预设底色:pi 默认深底 #1E1E1E、浅底 #F5F5F5、#121212、纯黑 #000000;ANSI 16 色仍是 pi 的 DEFAULT_ANSI,只换底色
  • 自定义底色:#RRGGBB 输入 + 色相/饱和度/明度三条滑杆(HSV 直改,不走 RGB 反算,修掉色相 360° 回跳与饱和度归零丢色相)
  • 色彩强度三档(素 / 标准 / 鲜艳)走 pi 推导函数的 saturation 参数
  • 拖动只预览,按「应用」才写盘:页内用真实 deriveSystemPalette 做页面 / 卡片 / 文字 / 强调四个预览块,不触发全 App 重组
  • 默认主题改成 system:底色一换,整套 56 个 token 跟着重算;明暗由底色亮度决定(这是 pi 自己的规则)
  • 修掉「整页染蓝」——页面与卡片底色改用选中的背景色本身,不再从 userMessageBg 缩放

悬浮输入框

输入框从贴着屏幕底边改成真正悬浮:

  • 12 / 8 边距、26dp 圆角、中性阴影、聚焦时描边 1.5 → 2dp、运行中呼吸
  • 6 行自适应高度
  • 工具行 32 圆形按钮 / 20 字形,引导 / 后续回到键行
  • 输入框下方不再实心铺到屏底:卡片背后实心,卡片下边缘画 24dp 的页面底色 → 透明渐隐,与上边缘对称,8dp 缝和导航条自然透出列表
  • 去掉 6dp 投影——浅色下它落在下面那行卡片上,就是输入框与导航条之间那条灰带
  • 关掉导航条系统遮罩:SystemBarStyle.auto 会在 API 29+ 把 isNavigationBarContrastEnforced 重新设成 true,覆盖 XML 的设置,浅色下系统于是在导航条上盖一层约 90% 白遮罩

模型能力:每条模型都能改

以前只有导入那一刻能设能力,之后只能看。现在导入时与导入后共用同一支表单:

  • 可调:上下文 token、最大输出 token、支持图片、输入 / 输出价、缓存读 / 写价(美元 / 百万 token)、推理
  • 留空 = 不写这个键,交还 pi 的默认(128000 / 16384 / 仅文本 / 0),与「填 0」严格区分
  • 没碰过的开关不写:只改价格不会顺手把 reasoning 或图片能力写成 false
  • 预填顺序:申报过的定义 → 引擎快照 → pi 目录(反过来会把上次改的值一打开就盖回官方值)
  • 「恢复 pi 默认」= 删掉这条申报
  • 写入只动 models[] 里同 id 的那一条,其余模型与厂商块上的未知键按 id 合并保留

models.dev 接入:自动补思考档位与缺失能力

没有任何厂商的 /models 会回思考档位——这就是以前只有一家能思考的原因。models.dev 是 pi 目录的上游(pi 自己的 generate-models.ts 就吃它),232 家厂商、几千个模型:

  • 解析 api.json → 精确 厂商/模型 + 裸 模型 id 两级索引
  • reasoning_options 按 pi 自己的 getEffortThinkingLevelMap 逐条生成 thinkingLevelMap(off/minimal/low/medium/high/xhigh/max,未支持写 null,一个都没有就不写)
  • 约 6 MB 缓存到本地、7 天有效;只在扫描回来的模型缺上下文时取一次,失败或断网就跳过,绝不让导入失败
  • 候选的元数据来源补齐为五级:目录 → 引擎 → 本次扫描 → 跨厂商目录 → models.dev

顺带修掉一批元数据采集:中转站的 /models 通常只回 id,以前一律落到 pi 默认值,看起来像随便填的。现在按语义认五家拼法——

字段 认得的写法
上下文 context_length / context_window / max_context_length(LM Studio) / max_model_len(vLLM、SGLang) / max_input_tokens / inputTokenLimit(Google) / limit.context(models.dev)
最大输出 top_provider.max_completion_tokens / max_output_tokens / max_completion_tokens / outputTokenLimit / limit.output
图片 architecture.input_modalities / capabilities.vision(Ollama、LM Studio) / modalities.input / supports_vision
思考 reasoning / supports_reasoning / supports_thinking / capabilities 里的 thinking / supported_parameters 里的 reasoning 系列
缓存价 OpenRouter pricing.input_cache_read|input_cache_write / models.dev cost.cache_read|cache_write / LiteLLM cache_read_input_token_cost

价格三种单位各按各的换算(OpenRouter per-token、models.dev per-million、LiteLLM per-token),厂商 per-token 价只在 PiScanVendorMeta 里乘一次到 per-million,表单与 models.json 都是 per-million。

跨厂商借定义:中转站转的 gpt-4o / claude-sonnet-4-5 / deepseek-chat 在 pi 随包目录里本来就有真数据,只是不在这一家的文件里。精确 id 与 vendor/model 两种拼法都试——但价格不跨厂商借,定价不是一回事。

  • 采样参数:OpenRouter 的 default_parameters(468 个模型里 271 个有)读成 pi 的 samplingParams 原样写进模型定义——那是厂商给的默认值,不是替它调参
  • 接回「切换到下一个模型」:切完立刻更新 meta.model 并提示「已切到 <名字>(provider)」,没得循环时明说

思源宋体:聊天正文换字体

  • 随包内置 Source Han Serif(OFL-1.1),最终采用官方 CN 可变字体,只保留 wght 400/600 两档,SemiBold 注册为 Bold —— **粗体** 用真实 600,不再是合成加粗
  • 从全量 SC 静态双字重(49.2 MB / APK +40.3 MB)瘦身到 CN 子集可变字体(25.1 MB / APK 约 +15.5 MB)
  • 只作用于聊天 Markdown 正文:标题、引用、列表、表格用宋体;行内代码与代码块仍是 JetBrains Mono;界面文字仍是系统 Sans
  • 列表圆点改用界面字体——思源宋体的全宽 U+2022 会把列表正文整体右移
  • 许可证全文、组件清单、生成器 pin 同步更新

UI 一致性门禁(CI)

新增三条规则,无 JDK、无 SDK,纯 grep / sed / awk:

  1. 硬失败:只有 PiSheet.kt 能调 ModalBottomSheet
  2. 棘轮:按文件的 MaterialTheme.typography 计数只许降不许升
  3. 棘轮:screens / chat / settings 的裸 .dp / .sp 总数对着基线只许降不许升

界面重做

导航:拆掉底栏

  • Scaffold 不再有 bottomBar,底栏组件与图标集整套删除
  • 工作区 / 设置改走顶栏入口;对话页 ⋯ 菜单末尾也加了这两项
  • 关闭 ✕ 换成左侧返回箭头,退回行为不变
  • 返回键按条件互斥:覆盖层开着先关覆盖层,否则按设置栈逐级回退
  • 底栏拆掉后底距自动变成系统导航条 inset;全程只有 Scaffold 一处 imePadding

弹层统一:PiSheet

新增全 App 唯一弹层外壳 PiSheet:顶部圆角 20、36×3 把手、遮罩 0x8C000000、surfaceContainerHigh 底、一次展开。聊天的六个 sheet(模型选择 / 思考等级 / 会话工具 / 上下文 / 会话统计 / 分叉选择)全部换壳,设置的三处弹层也并了进来。

顶栏

  • 共享 PiTopBar:56 高、16 SemiBold 标题、48 热区 + 24 字形、圆形按压区
  • 颜色从 surfaceDim 改为页面底色(pi 的 pageBg),修掉浅色主题下状态栏那条色块
  • 发丝线与 12dp 渐隐只在滚动时出现,停下即收回
  • 对话页删掉模型 chip,右侧只剩搜索 / 工作区 / ⋮,标题拿回完整会话名的宽度

排版:四档全部重新定标

  • 经典档不再是「最挤最细」那一档:正文从 14/23 字重 400 改为 15/24 500,块距、列表、缩进、消息间隙、行内代码全部对齐舒适档
  • 列表:紧凑/舒适/宽松项上下内边距 4/8/8 → 3/4/5,项间实际 6/8/10
  • 分割线:非经典 0.75dp、上下各加 4dp,总间距 12/16/24;经典 1dp 不加
  • 标题:h1–h6 额外上边距 16/12/8/4(首块、或前一块也是标题时不叠加);h1 去掉下划线,靠字号与字重分层
  • 标题行高:舒适 25/30…17/22,紧凑/宽松同比例,经典保持原密度
  • 行内代码:字重 600 → 500
  • 表格:列宽不再固定 160,按可用宽拟合(最小 120,低于才横滑并画右缘渐隐);表头底色裁上圆角

会话页

  • 搜索框默认收起,顶栏加放大镜(展开动画 + 自动聚焦),把常驻的 48dp 还给列表
  • 分段控件、筛选 chip、筛后条数合成一行
  • 行改两行:标题 + 相对时间 /「模型 · N条」+ 按需出现的标签
  • 当前会话标识改版:描边胶囊 → 行底 selectedBg 35% + 左缘 3dp 主色竖条 + 标题 SemiBold
  • 卡内行间线 1dp 不透明 → 0.5dp outlineVariant
  • 新建按钮改用主题容器色

工作区:拆成两页

  • 顶栏只留返回 + 标题 + 刷新 / ⋯;引擎状态行删除,两段常驻说明挪进 ⋯ →「关于工作区」
  • 新增**「文件 / 资源」分段**
  • 文件页:目录卡压成芯片、面包屑只显示最后三级(前面折成可点的省略号)、文件名改无衬线 15/Medium、图标放进 32dp 圆角底
  • 资源页:技能/提示词/扩展/主题改成带计数的 chip,按来源分组,描述最多两行,行尾动作改成「复制名字」
  • 图标列统一 32dp 圆角底,行间线对齐到文字列;等宽只留给路径与命令
  • 修 YAML:description 的 | / > / >- 块标量按缩进取正文,不再把标记符当描述

模型页

  • 一屏收口:导入按钮上移、厂商卡头直接显示「N 个模型 · x 可用 · y 缺凭证 · z 等待重启」
  • 导入页分节、能力收成 chip、默认值说明从每行重复改为列表上方出现一次、手动模型名默认收起
  • 「pi 目录里有」不再每行重复;扫描与保存改成真按钮
  • 删掉**「本地模型(llama.cpp)」按钮**——它和「导入模型」是同一个 sheet,只是预选一档;手机上本来也跑不了 llama.cpp(pi 的 /llama 只在 TUI 里工作)
  • 凭证区加「移除」:只删 Key,保留厂商块与模型
  • 默认模型 / 默认厂商 / 循环模型三行收进同一张卡
  • 候选列表改懒加载、一次最多画 500 行(覆盖 OpenRouter 的约 470 个端点)

设置

  • 整块移除设置搜索(页面、入口、注册表 search API、测试一并删掉)
  • 首页重排:高频在上、与 pi 无关的合并到底部;安全与隐私、开源许可收进「其他」
  • 主题改成全屏选择、跟随系统改为列表
  • 统一卡片与行组件,去掉分组标题与文字尾巴;长文本行只显示字数,值封顶 40%

系统主题调色页

  • 三条色相/饱和度/明度滑杆改用 M3 Slider:游标居中、可拖、两端可达、48dp 触摸高度
  • 滑杆直接改 HSV,修掉色相 360° 回跳 0、饱和度为 0 或明度为 0 时丢色相
  • 页面重排:常用底色 → 三条滑杆(带数值读数)→ 色彩强度 → HEX → 应用

修复

  • 触底跟随锚点:pinToTail 以 viewportEndOffset - contentPadding.bottom 为列表终点,不再把屏幕底边当终点;流式越过输入框安全区的情况加了反例测试
  • 顶栏颜色:surfaceDim → background,状态栏透明时顶栏与页面同面
  • 订阅状态读错文件:引擎把 agentDir 绑到持久那份,/login 与订阅登录写的是镜像里的 auth.json,此前只读「优先 primary」那份会看不见 oauth 条目
  • 订阅登录失败信息:Node 的 fetch failed 把真正原因藏在 error.cause(ENOTFOUND / ECONNREFUSED / 证书),现在最多三层 cause 与 code 拼进错误信息
  • 新会话被顶掉:不再被「第一个 scoped 模型」抢占默认模型
  • 编辑官方模型:不再抹掉思考档位与采样参数;6 MB 的 models.dev 下载不再卡住扫描;Key 去空白
  • 删除厂商/模型:立刻从清单消失,不用等引擎重启;删厂商时清掉指向它的默认与循环条目
  • 两个开关点了没反应(推理设置);思考等级不再提供 off,默认显示 pi 的 medium
  • 工作区新建:落在当前层,不再拼 rootfs 相对路径;名字输入框改 48 高并带占位与校验
  • 错误卡去描边,保留错误底色与左侧色条
  • 思考卡去掉右侧「展开」+ 箭头,整块仍是点按切换
  • 回到底部按钮:视觉 36 / 点击 48;下箭头只在离开底部时出现,视觉底边在输入框顶边上方 12;上箭头约两屏后才出现
  • 清理重构后没有调用方的东西,扫掉过期注释

构建信息

引擎 @earendil-works/pi-coding-agent 1.3.0(未变)
变体 sideload28(targetSdk 28,默认选这个)
架构 arm64
安装包 157,701,973 字节(150.4 MiB)
sha256 5e8a4540f87ae40723f66ed650c3ddc62e1e997aa514c782d850f4617108bb83
来源 CI run #559,commit f2875ea6

同一密钥签名,可以覆盖安装,升级不丢数据。
这一版 APK 比上一版大 约 15 MiB,是内置的思源宋体 CN 可变字体。