lonny-agent 0.2.3 → 0.2.6

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.
Files changed (129) hide show
  1. package/README.md +326 -326
  2. package/dist/agent/index.js +1 -1
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/agent/llm.d.ts +4 -0
  5. package/dist/agent/llm.d.ts.map +1 -1
  6. package/dist/agent/project.d.ts +26 -0
  7. package/dist/agent/project.d.ts.map +1 -0
  8. package/dist/agent/project.js +303 -0
  9. package/dist/agent/project.js.map +1 -0
  10. package/dist/agent/prompt-builder.d.ts +1 -1
  11. package/dist/agent/prompt-builder.d.ts.map +1 -1
  12. package/dist/agent/prompt-builder.js +22 -13
  13. package/dist/agent/prompt-builder.js.map +1 -1
  14. package/dist/agent/providers/anthropic.d.ts.map +1 -1
  15. package/dist/agent/providers/anthropic.js +20 -2
  16. package/dist/agent/providers/anthropic.js.map +1 -1
  17. package/dist/agent/providers/google.d.ts.map +1 -1
  18. package/dist/agent/providers/google.js +1 -1
  19. package/dist/agent/providers/google.js.map +1 -1
  20. package/dist/agent/providers/ollama.d.ts.map +1 -1
  21. package/dist/agent/providers/ollama.js +2 -1
  22. package/dist/agent/providers/ollama.js.map +1 -1
  23. package/dist/agent/providers/openai.d.ts.map +1 -1
  24. package/dist/agent/providers/openai.js +63 -3
  25. package/dist/agent/providers/openai.js.map +1 -1
  26. package/dist/agent/session.d.ts +8 -2
  27. package/dist/agent/session.d.ts.map +1 -1
  28. package/dist/agent/session.js +250 -153
  29. package/dist/agent/session.js.map +1 -1
  30. package/dist/config/index.d.ts.map +1 -1
  31. package/dist/config/index.js +7 -1
  32. package/dist/config/index.js.map +1 -1
  33. package/dist/tools/__tests__/bash.test.js +1 -1
  34. package/dist/tools/__tests__/bash.test.js.map +1 -1
  35. package/dist/tools/__tests__/edit.test.js +875 -371
  36. package/dist/tools/__tests__/edit.test.js.map +1 -1
  37. package/dist/tools/__tests__/grep.test.js +32 -0
  38. package/dist/tools/__tests__/grep.test.js.map +1 -1
  39. package/dist/tools/__tests__/sed.test.d.ts +2 -0
  40. package/dist/tools/__tests__/sed.test.d.ts.map +1 -0
  41. package/dist/tools/__tests__/sed.test.js +228 -0
  42. package/dist/tools/__tests__/sed.test.js.map +1 -0
  43. package/dist/tools/bash.d.ts.map +1 -1
  44. package/dist/tools/bash.js +83 -10
  45. package/dist/tools/bash.js.map +1 -1
  46. package/dist/tools/edit.d.ts +58 -0
  47. package/dist/tools/edit.d.ts.map +1 -1
  48. package/dist/tools/edit.js +366 -149
  49. package/dist/tools/edit.js.map +1 -1
  50. package/dist/tools/grep.d.ts.map +1 -1
  51. package/dist/tools/grep.js +54 -30
  52. package/dist/tools/grep.js.map +1 -1
  53. package/dist/tools/read.d.ts +6 -0
  54. package/dist/tools/read.d.ts.map +1 -1
  55. package/dist/tools/read.js +42 -15
  56. package/dist/tools/read.js.map +1 -1
  57. package/dist/tools/registry.d.ts +0 -6
  58. package/dist/tools/registry.d.ts.map +1 -1
  59. package/dist/tools/registry.js +2 -33
  60. package/dist/tools/registry.js.map +1 -1
  61. package/dist/tools/sed.d.ts +4 -0
  62. package/dist/tools/sed.d.ts.map +1 -0
  63. package/dist/tools/sed.js +121 -0
  64. package/dist/tools/sed.js.map +1 -0
  65. package/dist/tools/write_plan.d.ts +1 -1
  66. package/dist/tools/write_plan.d.ts.map +1 -1
  67. package/dist/tools/write_plan.js +14 -4
  68. package/dist/tools/write_plan.js.map +1 -1
  69. package/dist/tui/index.d.ts.map +1 -1
  70. package/dist/tui/index.js +5 -4
  71. package/dist/tui/index.js.map +1 -1
  72. package/dist/web/index.d.ts.map +1 -1
  73. package/dist/web/index.js +30 -7
  74. package/dist/web/index.js.map +1 -1
  75. package/dist/web/public/app.js +5 -855
  76. package/dist/web/public/confirm.js +70 -0
  77. package/dist/web/public/index.html +121 -120
  78. package/dist/web/public/input.js +107 -0
  79. package/dist/web/public/messages.js +395 -0
  80. package/dist/web/public/sidebar.js +82 -0
  81. package/dist/web/public/state.js +72 -0
  82. package/dist/web/public/style.css +996 -949
  83. package/dist/web/public/utils.js +37 -0
  84. package/dist/web/public/websocket.js +267 -0
  85. package/dist/web/public/ws.js +19 -0
  86. package/dist/web/session-bridge.d.ts.map +1 -1
  87. package/dist/web/session-bridge.js +3 -7
  88. package/dist/web/session-bridge.js.map +1 -1
  89. package/package.json +55 -54
  90. package/scripts/copy-native.mjs +24 -0
  91. package/scripts/copy-web.mjs +15 -0
  92. package/src/agent/index.ts +25 -25
  93. package/src/agent/llm.ts +4 -0
  94. package/src/agent/project.ts +366 -0
  95. package/src/agent/prompt-builder.ts +23 -13
  96. package/src/agent/providers/anthropic.ts +179 -172
  97. package/src/agent/providers/google.ts +210 -211
  98. package/src/agent/providers/ollama.ts +186 -182
  99. package/src/agent/providers/openai.ts +73 -5
  100. package/src/agent/session.ts +275 -153
  101. package/src/config/index.ts +342 -335
  102. package/src/tools/__tests__/bash.test.ts +1 -1
  103. package/src/tools/__tests__/edit.test.ts +981 -385
  104. package/src/tools/__tests__/grep.test.ts +35 -0
  105. package/src/tools/bash.ts +97 -11
  106. package/src/tools/edit.ts +414 -154
  107. package/src/tools/git.ts +76 -76
  108. package/src/tools/grep.ts +57 -30
  109. package/src/tools/read.ts +61 -25
  110. package/src/tools/registry.ts +231 -265
  111. package/src/tools/write_plan.ts +21 -5
  112. package/src/tui/index.ts +786 -785
  113. package/src/web/index.ts +29 -7
  114. package/src/web/public/app.js +5 -855
  115. package/src/web/public/confirm.js +70 -0
  116. package/src/web/public/index.html +121 -120
  117. package/src/web/public/input.js +107 -0
  118. package/src/web/public/messages.js +395 -0
  119. package/src/web/public/sidebar.js +82 -0
  120. package/src/web/public/state.js +72 -0
  121. package/src/web/public/style.css +996 -949
  122. package/src/web/public/utils.js +37 -0
  123. package/src/web/public/websocket.js +267 -0
  124. package/src/web/public/ws.js +19 -0
  125. package/src/web/session-bridge.ts +193 -194
  126. package/.kilo/plans/1780064105789-mighty-pixel.md +0 -171
  127. package/.kilo/plans/1780293725888-quick-wizard.md +0 -62
  128. package/.lonny/plan-web-cwd-status.md +0 -38
  129. package/src/tools/exec.ts +0 -348
package/README.md CHANGED
@@ -1,326 +1,326 @@
1
- # lonny — 用更少的调用做更多的事
2
-
3
- > 一个专为 Coding Plan(5 小时 1200 次调用套餐)场景优化的 AI 编码代理,目标是用更少的 API 调用次数完成更多的工作。支持三模式操作(code/plan/ask)、多模型供应商、批量编辑和美观的终端界面。
4
-
5
- ---
6
-
7
- ## 功能特性
8
-
9
- - **三模式操作**:`code` 模式直接编辑代码文件,`plan` 模式生成可执行的计划文档,`ask` 模式仅限问答和网络搜索
10
- - **多模型支持**:兼容 Anthropic(Claude)、OpenAI(GPT)、Google(Gemini)、Ollama(本地模型),支持切换
11
- - **批量编辑**:单次调用支持多文件、多位置的批量编辑,优化按调用付费的成本
12
- - **语法高亮**:内置代码块语法高亮(TypeScript、Python、Rust、Go、Shell 等十余种语言)
13
- - **会话持久化**:自动保存和恢复会话(`~/.lonny/sessions/`),支持 mid-turn 保存防止刷新数据丢失
14
- - **Token 统计**:实时追踪输入/输出 token 用量和 API 调用次数
15
- - **技能系统**:通过 `.lonny/skills/` 加载自定义技能提示(Markdown + frontmatter)
16
- - **模板系统**:通过 `.lonny/prompts/` 加载可复用的提示模板,支持参数替换(`$1`, `$2`, `$@`)
17
- - **计划管理**:`plan` 模式下生成可复用的计划文档(`.lonny/plans/`),TUI 中支持查看和筛选
18
- - **思考过程展示**:支持 Anthropic/OpenAI 推理模型(thinking/reasoning_effort),实时流式显示思考过程
19
- - **上下文压缩**:长对话自动压缩(超过 128K token 的 75%),保留关键上下文和工具调用结果
20
- - **工具注册表**:可扩展的工具插件系统,支持动态注册/注销工具
21
- - **exec 工具**:在沙箱中执行 JavaScript 代码,可编排多个工具调用
22
- - **美观的 TUI**:像素字体 Logo、状态栏(cwd + 模式 + token 统计 + 模型)、Todo 侧边栏、实时加载动画
23
- - **DeepSeek 余额查询**:自动查询 DeepSeek 账户余额并显示在状态栏
24
- - **事件总线**:内部事件系统,支持 TUI 实时更新工具调用状态
25
- - **Web UI**:通过浏览器访问的 Web 聊天界面,支持流式输出、工具调用可视化、工作目录展示、DeepSeek 余额查询、斜杠命令补全、会话历史恢复和模式/模型切换
26
- - **代码质量管道**:内置 Biome 检查、Husky Git hooks、lint-staged 自动格式化
27
-
28
- ## 快速开始
29
-
30
- ### 安装
31
-
32
- ```bash
33
- npm install -g lonny-agent
34
- ```
35
-
36
- ### 配置
37
-
38
- 配置文件 `~/.lonny/config.json`(通过 `lonny init` 自动生成):
39
-
40
- ```json
41
- {
42
- "provider": "openai",
43
- "model": "deepseek-v4-flash",
44
- "baseUrl": "https://api.deepseek.com",
45
- "apiKey": "sk-...",
46
- "autoApprove": false,
47
- "tavilyApiKey": "tvly-...",
48
- "thinking": false,
49
- "reasoningEffort": "medium",
50
- "contextWindow": 256000,
51
- "strictTools": true
52
- }
53
- ```
54
-
55
- | 配置项 | 说明 | 默认值 |
56
- |--------|------|--------|
57
- | `provider` | 模型供应商:`openai`、`anthropic`、`google`、`ollama` | `openai` |
58
- | `model` | 模型名称 | `deepseek-v4-flash` |
59
- | `baseUrl` | API 地址 | `https://api.deepseek.com` |
60
- | `apiKey` | API 密钥 | — |
61
- | `autoApprove` | 自动批准工具执行(无需确认) | `false` |
62
- | `tavilyApiKey` | Tavily 搜索 API 密钥 | — |
63
- | `thinking` | 启用推理模型的思考过程展示 | `false` |
64
- | `reasoningEffort` | 推理强度:`low`、`medium`、`high` | `medium` |
65
- | `contextWindow` | 上下文窗口大小(token) | `256000` |
66
- | `strictTools` | 严格模式工具调用(确保参数符合 schema) | `true` |
67
-
68
- ### 启动
69
-
70
- ```bash
71
- # 启动交互式终端界面(TUI)
72
- lonny
73
-
74
- # 单次对话模式(非交互式)
75
- lonny -p "你的问题"
76
-
77
- # plan 模式
78
- lonny --mode plan
79
-
80
- # ask 模式
81
- lonny --mode ask -p "什么是 Rust 的所有权系统?"
82
-
83
- # Web UI 模式(浏览器访问 http://localhost:15090)
84
- lonny --web
85
-
86
- # 指定 Web UI 端口
87
- lonny --web --port 8080
88
- ```
89
-
90
- ## 命令行参数
91
-
92
- | 参数 | 说明 |
93
- |------|------|
94
- | `-p, --prompt <text>` | 单次对话模式,直接提问 |
95
- | `--mode <code\|plan\|ask>` | 模式:`code`(编辑代码)、`plan`(制定计划)、`ask`(问答搜索) |
96
- | `--auto-approve` | 自动批准工具执行(无需确认) |
97
- | `--web` | 启动 Web UI 模式(通过浏览器访问) |
98
- | `--port <num>` | Web UI 端口号(默认:15090) |
99
-
100
- ### DeepSeek 缓存支持
101
-
102
- 当使用 DeepSeek 模型时(模型名或 base URL 包含 `deepseek`),lonny 会自动启用 `enable_cache` 以利用 DeepSeek 的缓存功能,降低 API 调用成本。
103
-
104
- DeepSeek v4 flash 的默认上下文窗口为 256K token,可通过配置文件的 `contextWindow` 调整。
105
-
106
- ## Web UI 使用指南
107
-
108
- Lonny 提供了基于 WebSocket 的 Web 聊天界面,支持所有核心功能。
109
-
110
- ### 启动
111
-
112
- ```bash
113
- # 启动 Web UI(默认端口 15090)
114
- lonny --web
115
-
116
- # 指定端口
117
- lonny --web --port 8080
118
- ```
119
-
120
- 然后在浏览器中打开 `http://localhost:15090`。
121
-
122
- ### 功能
123
-
124
- - **流式输出**:实时显示 AI 回复,逐字符流式渲染
125
- - **工具调用可视化**:显示正在调用的工具及其结果
126
- - **思考过程展示**:支持 Anthropic/OpenAI 推理模型的思考过程实时展示
127
- - **工作目录展示**:状态栏显示当前工作目录
128
- - **DeepSeek 余额查询**:自动查询并显示余额
129
- - **会话历史恢复**:刷新后自动恢复对话历史
130
- - **斜杠命令补全**:输入 `/` 自动弹出可用命令列表
131
- - **模式切换**:通过 `/mode code|plan|ask` 切换模式
132
- - **模型切换**:通过 `/model <name>` 切换模型
133
- - **新会话**:通过 `/new` 开始新会话
134
- - **查看技能**:通过 `/skills` 列出已加载技能
135
- - **查看模板**:通过 `/prompts` 列出提示模板
136
- - **初始化目录**:通过 `/init` 创建 `.lonny/skills/` 和 `.lonny/prompts/`
137
- - **帮助**:通过 `/help` 查看所有命令
138
- - **自动重连**:连接断开后自动重连(最多尝试 10 次)
139
- - **心跳保活**:每 30 秒发送心跳保持连接
140
-
141
- ### WebSocket 消息协议
142
-
143
- 前后端通过 WebSocket 通信,消息格式为 JSON:
144
-
145
- **客户端 → 服务器:**
146
- ```
147
- { type: "message", text: "..." } // 发送消息
148
- { type: "load_plan", planName: "..." } // 加载计划
149
- { type: "tool_confirm_response", approved: true/false } // 工具确认
150
- { type: "stop" } // 停止
151
- { type: "ping" } // 心跳
152
- ```
153
-
154
- **服务器 → 客户端:**
155
- ```
156
- { type: "hello", mode, model, provider, cwd, balance, totalIn, totalOut, totalApi } // 初始状态
157
- { type: "session_history", messages: [...] } // 会话历史
158
- { type: "chunk", text: "..." } // 流式文本
159
- { type: "thinking", text: "..." } // 思考过程
160
- { type: "thinking_end" } // 思考结束
161
- { type: "turn_start" } // 新轮次开始
162
- { type: "tool_call", name, input, id } // 工具调用
163
- { type: "tool_result", name, success, output, id } // 工具结果
164
- { type: "turn_end", iterations, toolCallCount } // 轮次结束
165
- { type: "token_stats", turnIn, turnOut, totalIn, totalOut, turnApi, totalApi } // Token 统计
166
- { type: "done", reason: "stop" | "error" } // 完成
167
- { type: "error", message } // 错误
168
- { type: "mode_changed", mode } // 模式切换
169
- { type: "model_changed", model } // 模型切换
170
- { type: "session_cleared" } // 会话清除
171
- { type: "plan_written", display } // 计划已写入
172
- { type: "plan_data", plans, currentPlanName, todos } // 计划/Todo 数据
173
- { type: "balance_update", balance, webBalance } // 余额更新
174
- { type: "compaction", before, after } // 上下文压缩
175
- { type: "tool_confirm_request", toolCalls } // 工具执行确认
176
- { type: "help", commands } // 帮助信息
177
- { type: "pong" } // 心跳响应
178
- ```
179
-
180
- ## TUI 使用指南
181
-
182
- ### 命令
183
-
184
- | 命令 | 说明 |
185
- |------|------|
186
- | `/mode code\|plan\|ask` | 切换模式(代码编辑/计划制定/问答搜索) |
187
- | `/model <name>` | 切换模型 |
188
- | `/plans` | 查看计划列表 |
189
- | `/prompts` | 查看提示模板列表 |
190
- | `/skills` | 查看技能列表 |
191
- | `/filter <query>` | 筛选计划列表 |
192
- | `/new` | 开始新会话 |
193
- | `/stop` | 停止正在运行的代理 |
194
- | `/init` | 创建 `.lonny/skills/` 和 `.lonny/prompts/` 目录 |
195
- | `/help` | 显示帮助信息 |
196
- | `/exit` | 退出程序 |
197
-
198
- ### 快捷键
199
-
200
- | 按键 | 说明 |
201
- |------|------|
202
- | `Enter` | 发送消息 |
203
- | `↑/↓` | 浏览历史记录 |
204
- | `Tab` | 自动补全命令 |
205
- | `?` | 切换帮助面板 |
206
-
207
- ### 状态指示
208
-
209
- - **光标闪烁**:闲置状态,可以输入
210
- - **光标消失**:正在处理请求
211
- - **头部状态栏**:显示 `● running`(运行中)或 `○ idle`(闲置)
212
-
213
- ## 配置目录结构
214
-
215
- ```
216
- 项目目录/
217
- ├── .lonny/
218
- │ ├── skills/ # 自定义技能(.md 文件,支持 frontmatter)
219
- │ ├── prompts/ # 提示模板(.md 文件,支持 $1, $2, $@ 参数替换)
220
- │ └── plans/ # plan 模式下生成的计划文档
221
- └── ...
222
-
223
- ~/.lonny/
224
- ├── config.json # 全局配置文件
225
- └── sessions/ # 自动保存的会话(按项目目录哈希命名)
226
- ```
227
-
228
- ### 技能文件示例(`.lonny/skills/my-skill.md`)
229
-
230
- ```markdown
231
- ---
232
- name: my-skill
233
- description: 我的自定义技能
234
- ---
235
-
236
- 在这里写自定义的 AI 行为指令...
237
- ```
238
-
239
- ### 提示模板示例(`.lonny/prompts/fix-typo.md`)
240
-
241
- ```markdown
242
- ---
243
- name: fix-typo
244
- description: 修复文件中的拼写错误
245
- argument-hint: <file>
246
- ---
247
-
248
- 修复 $1 中的任何拼写错误
249
- ```
250
-
251
- 通过模板名称引用:`/prompts` 列出所有模板。
252
-
253
- ## 工具
254
-
255
- lonny 为 AI 模型提供了以下工具:
256
-
257
- | 工具 | 说明 | 可用模式 |
258
- |------|------|----------|
259
- | `read` | 读取文件内容 | code, plan |
260
- | `glob` | 使用 glob 模式搜索文件 | code, plan |
261
- | `grep` | 在文件中搜索文本 | code, plan |
262
- | `ls` | 列出目录内容 | code, plan |
263
- | `bash` | 执行 shell 命令 | code, plan |
264
- | `find` | 按名称搜索文件 | code, plan |
265
- | `git` | 执行只读 Git 操作 | code, plan |
266
- | `edit` | 批量编辑文件(多文件多位置),提供详细的错误诊断和字段验证 | code |
267
- | `write_plan` | 编写计划文档 | plan |
268
- | `exec` | 在沙箱中执行 JavaScript 编排多个工具 | code |
269
- | `install_skill` | 安装 npm 包或 ClawHub 技能 | code, plan |
270
- | `fetch` | 获取 URL 内容 | code, plan, ask |
271
- | `search` | 联网搜索(Tavily API) | code, plan, ask |
272
-
273
- > **注意**:`search` 工具需要配置 Tavily API 密钥。在 `~/.lonny/config.json` 中添加 `"tavilyApiKey": "tvly-..."` 即可启用。
274
-
275
- ## 模式对比
276
-
277
- | 特性 | code | plan | ask |
278
- |------|------|------|-----|
279
- | 读取/搜索文件 | ✅ | ✅ | ❌ |
280
- | 编辑文件 | ✅ | ❌ | ❌ |
281
- | 编写计划文档 | ❌ | ✅ | ❌ |
282
- | exec 沙箱编排 | ✅ | ❌ | ❌ |
283
- | 联网搜索/抓取 | ✅ | ✅ | ✅ |
284
- | 安装技能 | ✅ | ✅ | ❌ |
285
-
286
- ## 开发
287
-
288
- ```bash
289
- # 克隆仓库
290
- git clone <repo-url>
291
- cd lonny-agent
292
-
293
- # 安装依赖
294
- npm install
295
-
296
- # 开发模式运行
297
- npm run dev
298
-
299
- # 构建
300
- npm run build
301
-
302
- # 运行测试
303
- npm test
304
- ```
305
-
306
- ### 代码质量
307
-
308
- 项目使用 [Biome](https://biomejs.dev/) 进行代码检查和格式化,通过 [Husky](https://typicode.github.io/husky/) Git hooks 自动执行:
309
-
310
- ```bash
311
- # 手动检查和格式化
312
- npm run check
313
- npm run check:fix
314
-
315
- # 提交前自动检查(通过 lint-staged)
316
- npm run lint:fix
317
- npm run format
318
- ```
319
-
320
- 支持的 Git hooks:
321
- - **pre-commit**:对暂存的 `.ts`、`.js`、`.mjs` 文件运行 Biome 检查,对 `.json`、`.jsonc` 文件自动格式化
322
- - **commit-msg**:验证提交信息是否符合 conventional commits 格式(如 `feat:`, `fix:`, `chore:` 等)
323
-
324
- ## 许可证
325
-
326
- MIT
1
+ # lonny — 用更少的调用做更多的事
2
+
3
+ > 一个专为 Coding Plan(5 小时 1200 次调用套餐)场景优化的 AI 编码代理,目标是用更少的 API 调用次数完成更多的工作。支持三模式操作(code/plan/ask)、多模型供应商、批量编辑和美观的终端界面。
4
+
5
+ ---
6
+
7
+ ## 功能特性
8
+
9
+ - **三模式操作**:`code` 模式直接编辑代码文件,`plan` 模式生成可执行的计划文档,`ask` 模式仅限问答和网络搜索
10
+ - **多模型支持**:兼容 Anthropic(Claude)、OpenAI(GPT)、Google(Gemini)、Ollama(本地模型),支持切换
11
+ - **批量编辑**:单次调用支持多文件、多位置的批量编辑,优化按调用付费的成本
12
+ - **语法高亮**:内置代码块语法高亮(TypeScript、Python、Rust、Go、Shell 等十余种语言)
13
+ - **会话持久化**:自动保存和恢复会话(`~/.lonny/sessions/`),支持 mid-turn 保存防止刷新数据丢失
14
+ - **Token 统计**:实时追踪输入/输出 token 用量和 API 调用次数
15
+ - **技能系统**:通过 `.lonny/skills/` 加载自定义技能提示(Markdown + frontmatter)
16
+ - **模板系统**:通过 `.lonny/prompts/` 加载可复用的提示模板,支持参数替换(`$1`, `$2`, `$@`)
17
+ - **计划管理**:`plan` 模式下生成可复用的计划文档(`.lonny/plans/`),TUI 中支持查看和筛选
18
+ - **思考过程展示**:支持 Anthropic/OpenAI 推理模型(thinking/reasoning_effort),实时流式显示思考过程
19
+ - **上下文压缩**:长对话自动压缩(超过 128K token 的 75%),保留关键上下文和工具调用结果
20
+ - **工具注册表**:可扩展的工具插件系统,支持动态注册/注销工具
21
+ - **exec 工具**:在沙箱中执行 JavaScript 代码,可编排多个工具调用
22
+ - **美观的 TUI**:像素字体 Logo、状态栏(cwd + 模式 + token 统计 + 模型)、Todo 侧边栏、实时加载动画
23
+ - **DeepSeek 余额查询**:自动查询 DeepSeek 账户余额并显示在状态栏
24
+ - **事件总线**:内部事件系统,支持 TUI 实时更新工具调用状态
25
+ - **Web UI**:通过浏览器访问的 Web 聊天界面,支持流式输出、工具调用可视化、工作目录展示、DeepSeek 余额查询、斜杠命令补全、会话历史恢复和模式/模型切换
26
+ - **代码质量管道**:内置 Biome 检查、Husky Git hooks、lint-staged 自动格式化
27
+
28
+ ## 快速开始
29
+
30
+ ### 安装
31
+
32
+ ```bash
33
+ npm install -g lonny-agent
34
+ ```
35
+
36
+ ### 配置
37
+
38
+ 配置文件 `~/.lonny/config.json`(通过 `lonny init` 自动生成):
39
+
40
+ ```json
41
+ {
42
+ "provider": "openai",
43
+ "model": "deepseek-v4-flash",
44
+ "baseUrl": "https://api.deepseek.com",
45
+ "apiKey": "sk-...",
46
+ "autoApprove": false,
47
+ "tavilyApiKey": "tvly-...",
48
+ "thinking": false,
49
+ "reasoningEffort": "medium",
50
+ "contextWindow": 256000,
51
+ "strictTools": true
52
+ }
53
+ ```
54
+
55
+ | 配置项 | 说明 | 默认值 |
56
+ |--------|------|--------|
57
+ | `provider` | 模型供应商:`openai`、`anthropic`、`google`、`ollama` | `openai` |
58
+ | `model` | 模型名称 | `deepseek-v4-flash` |
59
+ | `baseUrl` | API 地址 | `https://api.deepseek.com` |
60
+ | `apiKey` | API 密钥 | — |
61
+ | `autoApprove` | 自动批准工具执行(无需确认) | `false` |
62
+ | `tavilyApiKey` | Tavily 搜索 API 密钥 | — |
63
+ | `thinking` | 启用推理模型的思考过程展示 | `false` |
64
+ | `reasoningEffort` | 推理强度:`low`、`medium`、`high` | `medium` |
65
+ | `contextWindow` | 上下文窗口大小(token) | `256000` |
66
+ | `strictTools` | 严格模式工具调用(确保参数符合 schema) | `true` |
67
+
68
+ ### 启动
69
+
70
+ ```bash
71
+ # 启动交互式终端界面(TUI)
72
+ lonny
73
+
74
+ # 单次对话模式(非交互式)
75
+ lonny -p "你的问题"
76
+
77
+ # plan 模式
78
+ lonny --mode plan
79
+
80
+ # ask 模式
81
+ lonny --mode ask -p "什么是 Rust 的所有权系统?"
82
+
83
+ # Web UI 模式(浏览器访问 http://localhost:15090)
84
+ lonny --web
85
+
86
+ # 指定 Web UI 端口
87
+ lonny --web --port 8080
88
+ ```
89
+
90
+ ## 命令行参数
91
+
92
+ | 参数 | 说明 |
93
+ |------|------|
94
+ | `-p, --prompt <text>` | 单次对话模式,直接提问 |
95
+ | `--mode <code\|plan\|ask>` | 模式:`code`(编辑代码)、`plan`(制定计划)、`ask`(问答搜索) |
96
+ | `--auto-approve` | 自动批准工具执行(无需确认) |
97
+ | `--web` | 启动 Web UI 模式(通过浏览器访问) |
98
+ | `--port <num>` | Web UI 端口号(默认:15090) |
99
+
100
+ ### DeepSeek 缓存支持
101
+
102
+ 当使用 DeepSeek 模型时(模型名或 base URL 包含 `deepseek`),lonny 会自动启用 `enable_cache` 以利用 DeepSeek 的缓存功能,降低 API 调用成本。
103
+
104
+ DeepSeek v4 flash 的默认上下文窗口为 256K token,可通过配置文件的 `contextWindow` 调整。
105
+
106
+ ## Web UI 使用指南
107
+
108
+ Lonny 提供了基于 WebSocket 的 Web 聊天界面,支持所有核心功能。
109
+
110
+ ### 启动
111
+
112
+ ```bash
113
+ # 启动 Web UI(默认端口 15090)
114
+ lonny --web
115
+
116
+ # 指定端口
117
+ lonny --web --port 8080
118
+ ```
119
+
120
+ 然后在浏览器中打开 `http://localhost:15090`。
121
+
122
+ ### 功能
123
+
124
+ - **流式输出**:实时显示 AI 回复,逐字符流式渲染
125
+ - **工具调用可视化**:显示正在调用的工具及其结果
126
+ - **思考过程展示**:支持 Anthropic/OpenAI 推理模型的思考过程实时展示
127
+ - **工作目录展示**:状态栏显示当前工作目录
128
+ - **DeepSeek 余额查询**:自动查询并显示余额
129
+ - **会话历史恢复**:刷新后自动恢复对话历史
130
+ - **斜杠命令补全**:输入 `/` 自动弹出可用命令列表
131
+ - **模式切换**:通过 `/mode code|plan|ask` 切换模式
132
+ - **模型切换**:通过 `/model <name>` 切换模型
133
+ - **新会话**:通过 `/new` 开始新会话
134
+ - **查看技能**:通过 `/skills` 列出已加载技能
135
+ - **查看模板**:通过 `/prompts` 列出提示模板
136
+ - **初始化目录**:通过 `/init` 创建 `.lonny/skills/` 和 `.lonny/prompts/`
137
+ - **帮助**:通过 `/help` 查看所有命令
138
+ - **自动重连**:连接断开后自动重连(最多尝试 10 次)
139
+ - **心跳保活**:每 30 秒发送心跳保持连接
140
+
141
+ ### WebSocket 消息协议
142
+
143
+ 前后端通过 WebSocket 通信,消息格式为 JSON:
144
+
145
+ **客户端 → 服务器:**
146
+ ```
147
+ { type: "message", text: "..." } // 发送消息
148
+ { type: "load_plan", planName: "..." } // 加载计划
149
+ { type: "tool_confirm_response", approved: true/false } // 工具确认
150
+ { type: "stop" } // 停止
151
+ { type: "ping" } // 心跳
152
+ ```
153
+
154
+ **服务器 → 客户端:**
155
+ ```
156
+ { type: "hello", mode, model, provider, cwd, balance, totalIn, totalOut, totalApi } // 初始状态
157
+ { type: "session_history", messages: [...] } // 会话历史
158
+ { type: "chunk", text: "..." } // 流式文本
159
+ { type: "thinking", text: "..." } // 思考过程
160
+ { type: "thinking_end" } // 思考结束
161
+ { type: "turn_start" } // 新轮次开始
162
+ { type: "tool_call", name, input, id } // 工具调用
163
+ { type: "tool_result", name, success, output, id } // 工具结果
164
+ { type: "turn_end", iterations, toolCallCount } // 轮次结束
165
+ { type: "token_stats", turnIn, turnOut, totalIn, totalOut, turnApi, totalApi } // Token 统计
166
+ { type: "done", reason: "stop" | "error" } // 完成
167
+ { type: "error", message } // 错误
168
+ { type: "mode_changed", mode } // 模式切换
169
+ { type: "model_changed", model } // 模型切换
170
+ { type: "session_cleared" } // 会话清除
171
+ { type: "plan_written", display } // 计划已写入
172
+ { type: "plan_data", plans, currentPlanName, todos } // 计划/Todo 数据
173
+ { type: "balance_update", balance, webBalance } // 余额更新
174
+ { type: "compaction", before, after } // 上下文压缩
175
+ { type: "tool_confirm_request", toolCalls } // 工具执行确认
176
+ { type: "help", commands } // 帮助信息
177
+ { type: "pong" } // 心跳响应
178
+ ```
179
+
180
+ ## TUI 使用指南
181
+
182
+ ### 命令
183
+
184
+ | 命令 | 说明 |
185
+ |------|------|
186
+ | `/mode code\|plan\|ask` | 切换模式(代码编辑/计划制定/问答搜索) |
187
+ | `/model <name>` | 切换模型 |
188
+ | `/plans` | 查看计划列表 |
189
+ | `/prompts` | 查看提示模板列表 |
190
+ | `/skills` | 查看技能列表 |
191
+ | `/filter <query>` | 筛选计划列表 |
192
+ | `/new` | 开始新会话 |
193
+ | `/stop` | 停止正在运行的代理 |
194
+ | `/init` | 创建 `.lonny/skills/` 和 `.lonny/prompts/` 目录 |
195
+ | `/help` | 显示帮助信息 |
196
+ | `/exit` | 退出程序 |
197
+
198
+ ### 快捷键
199
+
200
+ | 按键 | 说明 |
201
+ |------|------|
202
+ | `Enter` | 发送消息 |
203
+ | `↑/↓` | 浏览历史记录 |
204
+ | `Tab` | 自动补全命令 |
205
+ | `?` | 切换帮助面板 |
206
+
207
+ ### 状态指示
208
+
209
+ - **光标闪烁**:闲置状态,可以输入
210
+ - **光标消失**:正在处理请求
211
+ - **头部状态栏**:显示 `● running`(运行中)或 `○ idle`(闲置)
212
+
213
+ ## 配置目录结构
214
+
215
+ ```
216
+ 项目目录/
217
+ ├── .lonny/
218
+ │ ├── skills/ # 自定义技能(.md 文件,支持 frontmatter)
219
+ │ ├── prompts/ # 提示模板(.md 文件,支持 $1, $2, $@ 参数替换)
220
+ │ └── plans/ # plan 模式下生成的计划文档
221
+ └── ...
222
+
223
+ ~/.lonny/
224
+ ├── config.json # 全局配置文件
225
+ └── sessions/ # 自动保存的会话(按项目目录哈希命名)
226
+ ```
227
+
228
+ ### 技能文件示例(`.lonny/skills/my-skill.md`)
229
+
230
+ ```markdown
231
+ ---
232
+ name: my-skill
233
+ description: 我的自定义技能
234
+ ---
235
+
236
+ 在这里写自定义的 AI 行为指令...
237
+ ```
238
+
239
+ ### 提示模板示例(`.lonny/prompts/fix-typo.md`)
240
+
241
+ ```markdown
242
+ ---
243
+ name: fix-typo
244
+ description: 修复文件中的拼写错误
245
+ argument-hint: <file>
246
+ ---
247
+
248
+ 修复 $1 中的任何拼写错误
249
+ ```
250
+
251
+ 通过模板名称引用:`/prompts` 列出所有模板。
252
+
253
+ ## 工具
254
+
255
+ lonny 为 AI 模型提供了以下工具:
256
+
257
+ | 工具 | 说明 | 可用模式 |
258
+ |------|------|----------|
259
+ | `read` | 读取文件内容 | code, plan |
260
+ | `glob` | 使用 glob 模式搜索文件 | code, plan |
261
+ | `grep` | 在文件中搜索文本 | code, plan |
262
+ | `ls` | 列出目录内容 | code, plan |
263
+ | `bash` | 执行 shell 命令 | code, plan |
264
+ | `find` | 按名称搜索文件 | code, plan |
265
+ | `git` | 执行只读 Git 操作 | code, plan |
266
+ | `edit` | 批量编辑文件(多文件多位置),提供详细的错误诊断和字段验证 | code |
267
+ | `write_plan` | 编写计划文档 | plan |
268
+ | `exec` | 在沙箱中执行 JavaScript 编排多个工具 | code |
269
+ | `install_skill` | 安装 npm 包或 ClawHub 技能 | code, plan |
270
+ | `fetch` | 获取 URL 内容 | code, plan, ask |
271
+ | `search` | 联网搜索(Tavily API) | code, plan, ask |
272
+
273
+ > **注意**:`search` 工具需要配置 Tavily API 密钥。在 `~/.lonny/config.json` 中添加 `"tavilyApiKey": "tvly-..."` 即可启用。
274
+
275
+ ## 模式对比
276
+
277
+ | 特性 | code | plan | ask |
278
+ |------|------|------|-----|
279
+ | 读取/搜索文件 | ✅ | ✅ | ❌ |
280
+ | 编辑文件 | ✅ | ❌ | ❌ |
281
+ | 编写计划文档 | ❌ | ✅ | ❌ |
282
+ | exec 沙箱编排 | ✅ | ❌ | ❌ |
283
+ | 联网搜索/抓取 | ✅ | ✅ | ✅ |
284
+ | 安装技能 | ✅ | ✅ | ❌ |
285
+
286
+ ## 开发
287
+
288
+ ```bash
289
+ # 克隆仓库
290
+ git clone <repo-url>
291
+ cd lonny-agent
292
+
293
+ # 安装依赖
294
+ npm install
295
+
296
+ # 开发模式运行
297
+ npm run dev
298
+
299
+ # 构建
300
+ npm run build
301
+
302
+ # 运行测试
303
+ npm test
304
+ ```
305
+
306
+ ### 代码质量
307
+
308
+ 项目使用 [Biome](https://biomejs.dev/) 进行代码检查和格式化,通过 [Husky](https://typicode.github.io/husky/) Git hooks 自动执行:
309
+
310
+ ```bash
311
+ # 手动检查和格式化
312
+ npm run check
313
+ npm run check:fix
314
+
315
+ # 提交前自动检查(通过 lint-staged)
316
+ npm run lint:fix
317
+ npm run format
318
+ ```
319
+
320
+ 支持的 Git hooks:
321
+ - **pre-commit**:对暂存的 `.ts`、`.js`、`.mjs` 文件运行 Biome 检查,对 `.json`、`.jsonc` 文件自动格式化
322
+ - **commit-msg**:验证提交信息是否符合 conventional commits 格式(如 `feat:`, `fix:`, `chore:` 等)
323
+
324
+ ## 许可证
325
+
326
+ MIT
@@ -18,7 +18,7 @@ export async function runAgent(prompt, config) {
18
18
  });
19
19
  },
20
20
  };
21
- const session = Session.load(config, output) || new Session(config, output);
21
+ const session = (await Session.load(config, output)) || new Session(config, output);
22
22
  await session.chat(prompt);
23
23
  }
24
24
  //# sourceMappingURL=index.js.map