@liguoshuai/pi-web-chat 1.1.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +93 -17
- package/bin/pi-web-chat.js +2 -1
- package/package.json +1 -1
- package/public/app.js +537 -38
- package/public/index.html +13 -1
- package/public/style.css +201 -12
- package/server.js +328 -28
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,94 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.6.0] - 2026-07-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **后台任务继续运行 (Background Task Persistence)**:
|
|
14
|
+
- 关闭浏览器/标签页不再强制中止正在生成的 pi 任务:后台 pi RPC 子进程保持**跑完当前这一轮**;重连后可看到完整结果。
|
|
15
|
+
- `PiAgent` 跟踪 `state`(`idle`/`streaming`)与 `pending` 请求。只有在“**无 WebSocket 且真正空闲**”(无 streaming 也无未响应请求)时才启动空闲回收计时。
|
|
16
|
+
- 时长型缓冲区:在后台期间渲染器产出的事件会被**离线缓存**到 `EVENT_BUFFER_SIZE`(默认 2000 条)的环形 buffer。新连接上来时自动 **回放**为 `backfill_start` → N 条原始事件 → `backfill_end` 三个阶段包裹的消息,便于前端精确“追到哪儿”。
|
|
17
|
+
- 新增 REST 端点 `GET /api/agents`:查看所有存活后台 pi 代理(`state`, `alive`, `busy`, `hasClients`, `uptimeMs`, `bufferedEvents`, 最近一条用户提示等)。常驻 npm 下载、上传、调试或后台 面板都可以利用。
|
|
18
|
+
- 新增环境变量:`MAX_AGENT_LIFETIME_MS`(默认 1800000 = 30分钟,硬上限超出强制 `SIGTERM`;设为 0 禁用)。防止后台代理失控常驻。
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **`IDLE_TIMEOUT_MS` 语义重要变更**:从“**断开后多久**杀进程”变为“**真正空闲后多久**才回收”(默认还是 5min)。如果断开后还在 streaming 或有余未完成的 RPC 请求,定时器不会触发,任务不会被中断。
|
|
22
|
+
- 首页顶栏重连后会同步服务器状态:收到 `backfill_end` 后会自动滚动到底,并恢复 `streaming` 状态(如仍在后台继续)。
|
|
23
|
+
- 首页增加优雅关闭:`SIGINT`/`SIGTERM` 会“逐个停止所有后台 pi 进程”后再退出,防止 server 重启时留下 zombie 进程。
|
|
24
|
+
- 不再支持“`IDLE_TIMEOUT_MS=0` 断开即杀”告诉——该环境变量现在表示“**禁用空闲回收**”。需要立刻释放内存,请改为正数(如 `5000`)或重启 server。
|
|
25
|
+
|
|
26
|
+
### 技术说明
|
|
27
|
+
- `PiAgent` 生命周期事件:`agent_start → state=streaming`;`agent_end/agent_settled → state=idle`;`pi_exit → state=idle`。这是“背景继续跑完”的关键开关。
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## [1.5.0] - 2026-07-26
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Idle timeout & concurrency control (内存保护增强)**:
|
|
35
|
+
- 新增 `IDLE_TIMEOUT_MS` 环境变量,可配置浏览器断开后保留 pi RPC 子进程的时间(默认 300000ms = 5 分钟,设为 0 即关闭自动清理)。
|
|
36
|
+
- 新增 `MAX_CONCURRENT_AGENTS` 环境变量,限制并发 pi 代理进程数(默认 0 = 无限制)。超限时新 WebSocket 连接返回 1013 (capacity) 并在控制台警告,防止多标签页把小内存机器挤爆。
|
|
37
|
+
- 新增 `IDLE_DROP_HEAP=1` 环境变量,空闲时尝试调用 `global.gc()` 主动释放 V8 堆,配合 `--expose-gc` 让内存更快回收到 OS,而非被动 swap。
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- `bin/pi-web-chat.js` 启动 server 时加入 `--expose-gc` 标志,支持上述主动内存释放。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## [1.4.2] - 2026-07-26
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- **移动端顶栏常驻与布局优化 (Sticky Topbar & Mobile Layout)**:
|
|
48
|
+
- 顶栏 `.topbar` 设置 `position: sticky; top: 0; flex-shrink: 0; z-index: 20;`,确保在手机端滚动聊天、弹起软键盘或屏高变化时**始终常驻固定在屏幕最上方**,绝不随聊天区域滚动或被挤压。
|
|
49
|
+
- 采用 Dynamic Viewport Height(`100dvh`),解决 iOS Safari 与 Android 移动浏览器地址栏/底部导航栏显示隐藏时的页面抖动与错位。
|
|
50
|
+
- 优化移动端工作目录胶囊(CWD Pill)、模型胶囊(Model Pill)与会话标题的宽度挤压与弹性截断(`text-overflow: ellipsis`),小屏手机下依然精致美观。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## [1.4.1] - 2026-07-26
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- **切换/加载历史会话模型精准显示**:
|
|
58
|
+
- 修复加载历史会话时由于后台进程启动时与 `get_state` 异步竞态导致右上角模型 Pill 显示不准确的问题。
|
|
59
|
+
- REST `/api/session` 接口现在自动从该会话的 JSONL 历史链中精确提取最后使用的模型 (`model`)。
|
|
60
|
+
- 切换会话时,前端能够零延迟(Instant)同步并渲染该会话对应的正确模型,同时支持 `model_select` 事件实时联动。
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## [1.4.0] - 2026-07-26
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
- **多端与多浏览器同步协同 (Multi-Device & Multi-Browser Session Sharing)**:
|
|
68
|
+
- **WebSocket 多连接池**:服务端 `PiAgent` 进程升级为多连接池(`Set<WebSocket>`),电脑、手机、平板可同时挂载到同一个正在运行的会话,所有端实时同步接收 AI 流式回答。
|
|
69
|
+
- **多端消息双向广播**:手机端发送 Prompt 或插入指导指令(Steer)时,电脑端无需刷新即可实时呈现用户消息并同步流式输出 AI 答复。
|
|
70
|
+
- **URL 参数关联与一键分享**:选择会话时自动更新浏览器 URL 参数(`?session=...`),分享 URL 或在手机侧边栏选中同个会话即可直接加入同一会话同步协同。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## [1.3.0] - 2026-07-26
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- **运行时实时插入/拦截指令 (Steer Instructions During Agent Turns)**:
|
|
78
|
+
- AI 正在思考、读取文件或执行命令(`streaming`)时,可以在输入框输入补充或修正要求。
|
|
79
|
+
- 输入框右侧会自动展示 **`🧭 插入指令`** 按钮,按 Enter 或点击按钮可实时将指令发送给 `pi` 代理进程(发送 `steer` 消息)。
|
|
80
|
+
- 聊天界面中插入的指令会展示带 **`🧭 指导指令`** 徽章的突出气泡,`pi` 接收后能在当前轮次中即时调整执行方向。
|
|
81
|
+
- 未输入内容时,按钮保持原有的 `■` 停止按钮功能。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## [1.2.0] - 2026-07-26
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
- **断线自动重连 (Auto Reconnect with Exponential Backoff)**:网页连接断开后前端启动指数退避自动重连(1s ~ 15s),并在侧边栏底部指示灯实时显示重连状态(`重连中 (x)`)。重连成功弹出“网络连接已恢复”提示。
|
|
89
|
+
- **双向心跳检测 (Heartbeat Ping/Pong)**:服务端每 30 秒发送 WS Protocol Ping 清理僵尸连接,前端每 15 秒发送应用层 Ping,超时 45 秒无响应自动切断重连。
|
|
90
|
+
- **重连会话状态同步 (State Restoration)**:重连后自动向服务端获取 `isStreaming` 状态。若生成已在后台完成则载入最新对话历史,若仍生成中则自动平滑接续流式输出。
|
|
91
|
+
- **一键复制功能 (Copy Buttons)**:
|
|
92
|
+
- **代码块/命令复制**:所有 Markdown 渲染的代码块顶部增加语言标签与“复制”按钮。
|
|
93
|
+
- **工具调用指令复制**:在工具调用(如 `bash` 命令执行)卡片标题栏增加“复制”按钮,方便快速复制命令。
|
|
94
|
+
- **回答全文复制**:在 `pi` 角色标签右侧新增“复制全文”按钮。
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
10
98
|
## [1.1.0] - 2026-07-26
|
|
11
99
|
|
|
12
100
|
### Added
|
|
@@ -30,27 +118,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
30
118
|
- **工具调用参数显示不全**:新增 `toolcall_delta` / `toolcall_end` 处理,用 `toolcall_end` 的最终 `toolCall.arguments` 刷新头部 args 显示。
|
|
31
119
|
- **同一 agent 多轮 agent message 互相污染**:`message_start`(assistant) 重置本块的 text/thinking 累加器,避免上一轮工具调用与下一轮文本串到一起。
|
|
32
120
|
|
|
33
|
-
### Added
|
|
34
|
-
- 会话切换时右侧完整历史恢复(通过 REST `/api/session` 重建 parent 链)
|
|
35
|
-
- 模型切换器(顶栏 pill,支持所有 pi 配置的模型)
|
|
36
|
-
- Tool-call 折叠块(实时输出、可展开/折叠)
|
|
37
|
-
- Thinking 折叠块
|
|
38
|
-
- 发送按钮双态(发送/停止)+ 红色停止态
|
|
39
|
-
- 新会话后侧边栏在 `agent_settled` 立即刷新(无需手动刷新页面)
|
|
40
|
-
|
|
41
|
-
### Changed
|
|
42
|
-
- 侧边栏会话项去除无意义的 `●` 圆点,改为 tooltip 显示完整 jsonl 路径
|
|
43
|
-
- 发送按钮禁用逻辑:仅在 wsConnected=false 时禁用,而非 streaming 时
|
|
44
|
-
|
|
45
121
|
---
|
|
46
122
|
|
|
47
123
|
## [0.2.0] - 2026-07-19
|
|
48
124
|
|
|
49
125
|
### Added
|
|
50
|
-
- **新建会话流程修复**:`btnNew` 点击后刷新侧边栏、清理流式状态、生成新 ws
|
|
51
|
-
- **WebSocket 代次机制**:`wsGen` 防止旧 socket
|
|
52
|
-
- **输入框红边提示**:ws 未连时提交会有 350ms 红色 flash
|
|
53
|
-
-
|
|
126
|
+
- **新建会话流程修复**:`btnNew` 点击后刷新侧边栏、清理流式状态、生成新 ws 代次。
|
|
127
|
+
- **WebSocket 代次机制**:`wsGen` 防止旧 socket 消息污染新上下文。
|
|
128
|
+
- **输入框红边提示**:ws 未连时提交会有 350ms 红色 flash。
|
|
129
|
+
- **连接状态文本动态更新**:「连接中…」→「已连接」/「已断开」。
|
|
54
130
|
- **提交**:`5a8f036` "Fix new-session flow: ws generation guard + sidebar refresh + drop input"
|
|
55
131
|
|
|
56
132
|
### Fixed
|
|
@@ -96,4 +172,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
96
172
|
| **Deprecated** | 即将移除 |
|
|
97
173
|
| **Removed** | 已移除 |
|
|
98
174
|
| **Fixed** | Bug 修复 |
|
|
99
|
-
| **Security** | 安全相关修复 |
|
|
175
|
+
| **Security** | 安全相关修复 |
|
package/bin/pi-web-chat.js
CHANGED
|
@@ -52,7 +52,8 @@ function parseArgs(argv) {
|
|
|
52
52
|
const opts = parseArgs(process.argv.slice(2));
|
|
53
53
|
|
|
54
54
|
// Spawn server.js as a child so we can forward signals cleanly.
|
|
55
|
-
|
|
55
|
+
// Use --expose-gc so idle agents can call global.gc() to release heap (IDLE_DROP_HEAP=1).
|
|
56
|
+
const child = spawn("node", ["--expose-gc", SERVER], {
|
|
56
57
|
cwd: opts.cwd,
|
|
57
58
|
env: { ...process.env, PORT: String(opts.port) },
|
|
58
59
|
stdio: "inherit",
|