Skip to content

Commit d1b7a1c

Browse files
author
Sisyphus Agent
committed
feat: add --timeout parameter to oho add command
- 新增 --timeout 参数支持临时设置超时时间 - 更新超时错误提示信息 - 完善文档说明 (README.md, README_zh.md, SKILL.md) - 添加超时配置优先级说明 相关文档: - ADD_COMMAND_TIMEOUT_ANALYSIS.md - ADD_TIMEOUT_FIX_SUMMARY.md - SKILL_UPDATE_SUMMARY.md
1 parent 7f0e9e8 commit d1b7a1c

9 files changed

Lines changed: 976 additions & 15 deletions

File tree

ADD_COMMAND_TIMEOUT_ANALYSIS.md

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
# oho add 命令超时问题分析报告
2+
3+
**分析时间**: 2026-03-24 10:30 (CST)
4+
**分析人**: nanobot 🐈
5+
6+
---
7+
8+
## 🔍 问题现象
9+
10+
用户反馈使用 `oho add` 命令时会超时。
11+
12+
---
13+
14+
## 📋 分析结果
15+
16+
### 1. 代码实现分析
17+
18+
#### add.go 执行流程
19+
20+
```go
21+
func runAdd(cmd *cobra.Command, args []string) error {
22+
// Step 1: 获取当前工作目录
23+
sessionDir := addDirectory
24+
if sessionDir == "" {
25+
sessionDir, _ = os.Getwd()
26+
}
27+
28+
// Step 2: 生成标题
29+
sessionTitle := addTitle
30+
if sessionTitle == "" {
31+
sessionTitle = fmt.Sprintf("New session - %s", time.Now().Format("2006-01-02T15:04:05"))
32+
}
33+
34+
// Step 3: 创建会话 ✅ (快速,通常 < 1 秒)
35+
sessionID, err := createSession(c, ctx, sessionTitle, addParent, sessionDir)
36+
37+
// Step 4: 发送消息 ⚠️ (可能超时)
38+
messageID, err := sendMessage(c, ctx, sessionID, message, addAgent, addModel, addNoReply, ...)
39+
40+
// Step 5: 输出结果
41+
...
42+
}
43+
```
44+
45+
#### sendMessage 函数
46+
47+
```go
48+
func sendMessage(...) (string, error) {
49+
// 构建消息请求
50+
msgReq := types.MessageRequest{
51+
Model: convertModel(model),
52+
Agent: agent,
53+
NoReply: noReply, // ⚠️ 关键:默认 false,会等待 AI 响应
54+
System: system,
55+
Tools: tools,
56+
Parts: parts,
57+
}
58+
59+
// 发送 POST 请求
60+
resp, err := c.Post(ctx, fmt.Sprintf("/session/%s/message", sessionID), msgReq)
61+
// ⚠️ 这里会等待 AI 响应,可能耗时很长
62+
...
63+
}
64+
```
65+
66+
#### client.go 超时配置
67+
68+
```go
69+
func NewClient() *Client {
70+
timeoutSec := 300 // 5 分钟
71+
if envTimeout := os.Getenv("OPENCODE_CLIENT_TIMEOUT"); envTimeout != "" {
72+
if parsed, err := strconv.Atoi(envTimeout); err == nil && parsed > 0 {
73+
timeoutSec = parsed
74+
}
75+
}
76+
77+
return &Client{
78+
httpClient: &http.Client{
79+
Timeout: time.Duration(timeoutSec) * time.Second,
80+
},
81+
}
82+
}
83+
```
84+
85+
---
86+
87+
## 🐛 问题根源
88+
89+
### 问题 1: 默认等待 AI 响应
90+
91+
**代码位置**: `add.go:sendMessage()`
92+
93+
```go
94+
NoReply: noReply, // 默认值:false
95+
```
96+
97+
**问题**:
98+
- `addNoReply` 默认值为 `false`
99+
- 这意味着 `oho add` 默认会**等待 AI 响应后才返回**
100+
- 对于复杂的 AI 任务(分析代码、重构等),5 分钟可能不够
101+
102+
**对比 `oho message add`**:
103+
```bash
104+
# oho message add 也需要 --no-reply 才不等待
105+
oho message add -s <session> "任务" # 等待响应
106+
oho message add -s <session> "任务" --no-reply # 不等待
107+
```
108+
109+
---
110+
111+
### 问题 2: 文档未说明超时配置
112+
113+
**文档位置**: `README.md`, `oho/README.md`
114+
115+
**缺失内容**:
116+
1. ❌ 未说明 `add` 命令默认会等待 AI 响应
117+
2. ❌ 未说明超时时间为 5 分钟
118+
3. ❌ 未说明如何通过环境变量调整超时
119+
4. ❌ 未建议使用 `--no-reply` 避免超时
120+
121+
**现有文档**:
122+
```markdown
123+
### Quick Start (Session + Message)
124+
125+
```bash
126+
oho add "帮我分析这个项目" # Create session and send message
127+
oho add "修复登录 bug" --title "Bug 修复" # Create session with custom title
128+
oho add "测试功能" --no-reply --agent default # Don't wait for AI response
129+
```
130+
```
131+
132+
**问题**: 虽然示例中有 `--no-reply`,但**没有解释为什么需要这个参数**
133+
134+
---
135+
136+
### 问题 3: 超时错误提示不友好
137+
138+
**代码位置**: `client.go:Request()`
139+
140+
```go
141+
resp, err := c.httpClient.Do(req)
142+
if err != nil {
143+
return nil, fmt.Errorf("请求失败:%w", err)
144+
}
145+
```
146+
147+
**问题**:
148+
- 超时错误只显示 "请求失败:context deadline exceeded"
149+
- 用户不知道可以调整超时时间
150+
- 没有建议解决方案
151+
152+
---
153+
154+
## ✅ 解决方案
155+
156+
### 方案 1: 修改文档(推荐,立即生效)
157+
158+
**修改文件**: `oho/README.md`, `README_zh.md`
159+
160+
**添加内容**:
161+
162+
```markdown
163+
### ⚠️ 超时注意事项
164+
165+
`oho add` 命令默认会等待 AI 响应后返回。对于复杂任务,AI 可能需要较长时间思考,可能导致超时。
166+
167+
**避免超时的方法**:
168+
169+
1. **使用 `--no-reply` 参数** (推荐):
170+
```bash
171+
# 发送消息后立即返回,不等待 AI 响应
172+
oho add "分析项目结构" --no-reply
173+
174+
# 稍后检查结果
175+
oho message list -s <session-id>
176+
```
177+
178+
2. **增加超时时间**:
179+
```bash
180+
# 设置超时为 10 分钟(600 秒)
181+
export OPENCODE_CLIENT_TIMEOUT=600
182+
oho add "复杂任务"
183+
184+
# 或临时设置
185+
OPENCODE_CLIENT_TIMEOUT=600 oho add "复杂任务"
186+
```
187+
188+
3. **使用异步命令**:
189+
```bash
190+
# 先创建会话
191+
oho session create --title "任务"
192+
193+
# 异步发送消息
194+
oho message prompt-async -s <session-id> "任务描述"
195+
```
196+
197+
**超时配置**:
198+
| 环境变量 | 默认值 | 说明 |
199+
|----------|--------|------|
200+
| `OPENCODE_CLIENT_TIMEOUT` | 300 秒 | HTTP 请求超时时间(秒) |
201+
202+
---
203+
204+
### 方案 2: 修改代码默认行为
205+
206+
**修改文件**: `oho/cmd/add/add.go`
207+
208+
**选项 A: 默认使用 `--no-reply`**
209+
210+
```go
211+
var (
212+
addNoReply bool = true // 改为默认 true
213+
)
214+
```
215+
216+
**优点**:
217+
- 避免大多数超时问题
218+
- 符合 CLI 工具的最佳实践(快速返回)
219+
220+
**缺点**:
221+
- 破坏向后兼容性
222+
- 用户可能期望立即看到 AI 响应
223+
224+
**选项 B: 添加超时提示**
225+
226+
```go
227+
func runAdd(cmd *cobra.Command, args []string) error {
228+
...
229+
230+
// 发送消息
231+
if !addNoReply {
232+
fmt.Println("⏳ 等待 AI 响应(按 Ctrl+C 中断,或使用 --no-reply 避免等待)...")
233+
}
234+
235+
messageID, err := sendMessage(...)
236+
...
237+
}
238+
```
239+
240+
---
241+
242+
### 方案 3: 改进错误提示
243+
244+
**修改文件**: `oho/internal/client/client.go`
245+
246+
```go
247+
resp, err := c.httpClient.Do(req)
248+
if err != nil {
249+
if strings.Contains(err.Error(), "context deadline exceeded") {
250+
return nil, fmt.Errorf("请求超时(%d 秒)\n\n建议:\n 1. 使用 --no-reply 参数避免等待\n 2. 设置环境变量增加超时:export OPENCODE_CLIENT_TIMEOUT=600\n 3. 使用异步命令:oho message prompt-async", timeoutSec)
251+
}
252+
return nil, fmt.Errorf("请求失败:%w", err)
253+
}
254+
```
255+
256+
---
257+
258+
### 方案 4: 添加超时配置标志
259+
260+
**修改文件**: `oho/cmd/add/add.go`
261+
262+
```go
263+
var (
264+
addTimeout int // 新增超时标志
265+
)
266+
267+
func init() {
268+
...
269+
Cmd.Flags().IntVar(&addTimeout, "timeout", 0, "请求超时时间(秒),0 使用默认值")
270+
}
271+
272+
func runAdd(cmd *cobra.Command, args []string) error {
273+
...
274+
275+
// 如果指定了超时,临时覆盖
276+
if addTimeout > 0 {
277+
os.Setenv("OPENCODE_CLIENT_TIMEOUT", strconv.Itoa(addTimeout))
278+
c = client.NewClient() // 重新创建客户端
279+
}
280+
281+
...
282+
}
283+
```
284+
285+
**使用方式**:
286+
```bash
287+
oho add "复杂任务" --timeout 600
288+
```
289+
290+
---
291+
292+
## 📝 推荐修复顺序
293+
294+
### 立即修复(今天)
295+
1.**修改文档** - 添加超时说明和解决方案
296+
2.**改进错误提示** - 超时错误给出明确建议
297+
298+
### 短期修复(本周)
299+
3.**添加超时标志** - `--timeout` 参数
300+
4.**添加等待提示** - 显示 "等待 AI 响应..."
301+
302+
### 长期考虑(下个版本)
303+
5.**讨论默认行为** - 是否默认 `--no-reply`
304+
6.**添加进度显示** - 显示 AI 思考进度
305+
306+
---
307+
308+
## 🔧 快速修复脚本
309+
310+
### 修复文档
311+
312+
```bash
313+
# 1. 更新 oho/README.md
314+
# 在 "Quick Start (Session + Message)" 部分后添加超时说明
315+
316+
# 2. 更新 README_zh.md
317+
# 同步中文文档
318+
```
319+
320+
### 修复错误提示
321+
322+
```bash
323+
# 修改 oho/internal/client/client.go
324+
# 在 Request() 函数中添加超时错误处理
325+
```
326+
327+
---
328+
329+
## 📊 影响评估
330+
331+
| 修复方案 | 影响范围 | 风险 | 优先级 |
332+
|----------|---------|------|--------|
333+
| 修改文档 | 用户文档 || P0 |
334+
| 改进错误提示 | 用户体验 || P0 |
335+
| 添加超时标志 | 新增功能 || P1 |
336+
| 修改默认行为 | 破坏性变更 || P2 |
337+
338+
---
339+
340+
## 🎯 结论
341+
342+
**主要原因**:
343+
1.**文档未说明** - 用户不知道 `add` 默认会等待 AI 响应
344+
2.**文档未说明超时配置** - 用户不知道可以调整超时时间
345+
3. ⚠️ 代码设计合理,但缺少用户友好的提示
346+
347+
**建议修复**:
348+
1. **立即更新文档**,说明超时配置和 `--no-reply` 用法
349+
2. **改进错误提示**,超时给出明确解决方案
350+
3. **考虑添加 `--timeout` 参数**,方便临时调整
351+
352+
**代码本身没有问题**,主要是**文档和用户引导不足**
353+
354+
---
355+
356+
*报告生成时间:2026-03-24 10:30 CST*

0 commit comments

Comments
 (0)