Repository navigation
PI 0.1.5(pi 1.3.0)· 订阅登录与界面重做
引擎:@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 可变字体,只保留
wght400/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:
- 硬失败:只有
PiSheet.kt能调ModalBottomSheet - 棘轮:按文件的
MaterialTheme.typography计数只许降不许升 - 棘轮:
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条」+ 按需出现的标签
- 当前会话标识改版:描边胶囊 → 行底
selectedBg35% + 左缘 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 可变字体。