Skip to content

Commit 5cc4817

Browse files
author
Sisyphus Agent
committed
feat: 添加问题排查文档和超时配置支持
新增文档: - docs/oho-cli-usage/09-troubleshooting.md: 完整的问题排查指南 - docs/oho-cli-usage/QUICK_REFERENCE.md: 快速参考卡片 - TIMEOUT_FIX_SUMMARY.md: 超时问题修复总结 新增脚本: - debug_message.sh: 自动诊断脚本,检查服务器、认证、会话状态 代码改进: - oho/internal/client/client.go: - 默认超时从 30 秒增加到 5 分钟 - 新增 OPENCODE_CLIENT_TIMEOUT 环境变量支持 - 解决 AI 长时间思考导致的超时问题 文档更新: - docs/oho-cli-usage/README.md: 添加模块 9 和快速参考卡片链接 修复问题: - 解决 'context deadline exceeded' 超时错误 - 消息提交成功但客户端等待超时的场景
1 parent 0674e74 commit 5cc4817

6 files changed

Lines changed: 1626 additions & 11 deletions

File tree

TIMEOUT_FIX_SUMMARY.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# 超时问题修复总结
2+
3+
## 问题描述
4+
5+
用户在使用 `oho message add` 提交消息时遇到超时错误:
6+
7+
```
8+
Error: 请求失败:Post "http://127.0.0.1:4096/session/.../message":
9+
context deadline exceeded (Client.Timeout exceeded while awaiting headers)
10+
```
11+
12+
## 问题分析
13+
14+
### 根本原因
15+
16+
客户端 HTTP 超时硬编码为 **30 秒**,对于需要长时间思考的 AI 任务来说太短了。
17+
18+
### 错误解读
19+
20+
这个错误**不是 Bug**,而是:
21+
- ✅ 请求已成功发送到服务器
22+
- ✅ 服务器正在处理(AI 正在思考)
23+
- ❌ 客户端等不及响应就断开了(30 秒超时)
24+
25+
### 实际情况
26+
27+
消息实际上已经提交成功,AI 可能正在处理,但 CLI 客户端在收到响应前就超时断开了。
28+
29+
---
30+
31+
## 解决方案
32+
33+
### 1. 代码修改
34+
35+
**文件**: `oho/internal/client/client.go`
36+
37+
**修改内容**:
38+
```go
39+
// 之前:硬编码 30 秒
40+
httpClient: &http.Client{
41+
Timeout: 30 * time.Second,
42+
}
43+
44+
// 之后:默认 5 分钟,支持环境变量配置
45+
timeoutSec := 300 // 5 分钟
46+
if envTimeout := os.Getenv("OPENCODE_CLIENT_TIMEOUT"); envTimeout != "" {
47+
if parsed, err := strconv.Atoi(envTimeout); err == nil && parsed > 0 {
48+
timeoutSec = parsed
49+
}
50+
}
51+
httpClient: &http.Client{
52+
Timeout: time.Duration(timeoutSec) * time.Second,
53+
}
54+
```
55+
56+
### 2. 新增环境变量
57+
58+
| 变量 | 默认值 | 说明 |
59+
|------|--------|------|
60+
| `OPENCODE_CLIENT_TIMEOUT` | 300 秒(5 分钟) | HTTP 请求超时时间 |
61+
62+
### 3. 使用方法
63+
64+
```bash
65+
# 使用默认超时(5 分钟)
66+
oho message add -s ses_xxx "任务"
67+
68+
# 设置更长超时(10 分钟)
69+
export OPENCODE_CLIENT_TIMEOUT=600
70+
oho message add -s ses_xxx "复杂任务"
71+
72+
# 不等待响应
73+
oho message add -s ses_xxx "任务" --no-reply
74+
75+
# 异步提交
76+
oho message prompt-async -s ses_xxx "任务"
77+
```
78+
79+
---
80+
81+
## 文档更新
82+
83+
### 新增/更新的文件
84+
85+
1. **docs/oho-cli-usage/09-troubleshooting.md**
86+
- 添加 "4.0 超时错误" 章节
87+
- 详细说明超时原因和解决方案
88+
89+
2. **docs/oho-cli-usage/QUICK_REFERENCE.md**
90+
- 添加超时配置说明
91+
- 添加超时错误速查项
92+
93+
3. **oho/internal/client/client.go**
94+
- 修改超时配置逻辑
95+
- 添加环境变量支持
96+
97+
---
98+
99+
## 验证步骤
100+
101+
```bash
102+
# 1. 重新编译
103+
cd /mnt/d/fe/opencode_cli/oho
104+
go build -o /usr/local/bin/oho ./cmd
105+
106+
# 2. 验证版本
107+
oho --help
108+
109+
# 3. 测试超时配置
110+
export OPENCODE_CLIENT_TIMEOUT=60
111+
oho message add -s ses_xxx "测试" --no-reply
112+
113+
# 4. 检查超时是否生效
114+
# 查看代码或运行诊断脚本
115+
./debug_message.sh
116+
```
117+
118+
---
119+
120+
## 最佳实践建议
121+
122+
### 超时配置建议
123+
124+
| 任务类型 | 推荐超时 | 说明 |
125+
|----------|----------|------|
126+
| 简单问答 | 60 秒 | 快速响应任务 |
127+
| 代码分析 | 300 秒(默认) | 中等复杂度任务 |
128+
| 复杂重构 | 600 秒 | 大型代码库分析 |
129+
| 批量任务 | 900 秒 | 多文件处理 |
130+
131+
### 避免超时的方法
132+
133+
1. **使用 `--no-reply`**: 发送消息但不等待响应
134+
2. **使用 `prompt-async`**: 异步提交任务
135+
3. **增加超时时间**: 设置 `OPENCODE_CLIENT_TIMEOUT`
136+
4. **简化任务**: 将大任务分解为小任务
137+
138+
---
139+
140+
## 技术细节
141+
142+
### HTTP 超时类型
143+
144+
| 超时类型 | 说明 | 当前配置 |
145+
|----------|------|----------|
146+
| Connection Timeout | 建立连接超时 | 由系统决定 |
147+
| Response Timeout | 等待响应超时 | 300 秒(可配置) |
148+
| Read Timeout | 读取数据超时 | 包含在 Response Timeout 中 |
149+
150+
### 超时的作用
151+
152+
- 防止客户端无限期等待
153+
- 释放卡住的连接
154+
- 避免资源浪费
155+
156+
### 为什么选择 5 分钟默认值
157+
158+
- 30 秒:太短,复杂任务会超时
159+
- 5 分钟:平衡大多数任务需求
160+
- 30 分钟:太长,可能掩盖服务器问题
161+
162+
---
163+
164+
*修复日期*: 2026-03-15
165+
*修复版本*: oho CLI v1.1+
166+
*相关文档*: docs/oho-cli-usage/09-troubleshooting.md

debug_message.sh

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#!/bin/bash
2+
# =============================================================================
3+
# OpenCode 消息提交调试脚本
4+
# =============================================================================
5+
# 用途:诊断为什么消息提交后没有 AI 响应
6+
# 使用:export OPENCODE_SERVER_PASSWORD=your-password && ./debug_message.sh
7+
# 参考:docs/oho-cli-usage/09-troubleshooting.md
8+
# =============================================================================
9+
10+
set -e
11+
12+
# 颜色定义
13+
RED='\033[0;31m'
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[1;33m'
16+
BLUE='\033[0;34m'
17+
NC='\033[0m'
18+
19+
# 配置(支持环境变量覆盖)
20+
SERVER_HOST="${OPENCODE_SERVER_HOST:-127.0.0.1}"
21+
SERVER_PORT="${OPENCODE_SERVER_PORT:-4096}"
22+
SERVER_PASSWORD="${OPENCODE_SERVER_PASSWORD:-}"
23+
SERVER_USERNAME="${OPENCODE_SERVER_USERNAME:-opencode}"
24+
BASE_URL="http://${SERVER_HOST}:${SERVER_PORT}"
25+
26+
echo "========================================="
27+
echo "OpenCode 消息提交调试脚本"
28+
echo "========================================="
29+
echo "服务器地址:${BASE_URL}"
30+
echo "用户名:${SERVER_USERNAME}"
31+
echo ""
32+
33+
# 1. 检查服务器健康状态
34+
echo -e "${YELLOW}[1/6] 检查服务器健康状态...${NC}"
35+
if curl -s -f "${BASE_URL}/global/health" > /dev/null 2>&1; then
36+
echo -e "${GREEN}✓ 服务器正常运行${NC}"
37+
else
38+
echo -e "${RED}✗ 服务器无法连接${NC}"
39+
echo "请确保 OpenCode 服务器正在运行:opencode serve"
40+
exit 1
41+
fi
42+
echo ""
43+
44+
# 2. 检查认证
45+
echo -e "${YELLOW}[2/6] 检查认证配置...${NC}"
46+
if [ -z "$SERVER_PASSWORD" ]; then
47+
echo -e "${RED}✗ 未设置 OPENCODE_SERVER_PASSWORD 环境变量${NC}"
48+
echo "请设置:export OPENCODE_SERVER_PASSWORD=your-password"
49+
exit 1
50+
else
51+
echo -e "${GREEN}✓ 密码已配置${NC}"
52+
fi
53+
54+
# 测试认证
55+
AUTH_RESULT=$(curl -s -w "%{http_code}" -u "opencode:${SERVER_PASSWORD}" "${BASE_URL}/config" 2>/dev/null)
56+
HTTP_CODE="${AUTH_RESULT: -3}"
57+
if [ "$HTTP_CODE" = "200" ]; then
58+
echo -e "${GREEN}✓ 认证成功${NC}"
59+
else
60+
echo -e "${RED}✗ 认证失败 (HTTP ${HTTP_CODE})${NC}"
61+
echo "请检查密码是否正确"
62+
exit 1
63+
fi
64+
echo ""
65+
66+
# 3. 列出会话
67+
echo -e "${YELLOW}[3/6] 获取会话列表...${NC}"
68+
SESSIONS=$(curl -s -u "opencode:${SERVER_PASSWORD}" "${BASE_URL}/session")
69+
SESSION_COUNT=$(echo "$SESSIONS" | grep -o '"id"' | wc -l)
70+
echo "找到 ${SESSION_COUNT} 个会话"
71+
72+
if [ "$SESSION_COUNT" -eq 0 ]; then
73+
echo -e "${YELLOW}! 没有现有会话,将创建一个新会话${NC}"
74+
CREATE_RESP=$(curl -s -X POST -u "opencode:${SERVER_PASSWORD}" \
75+
-H "Content-Type: application/json" \
76+
-d '{"title":"debug-session"}' \
77+
"${BASE_URL}/session")
78+
SESSION_ID=$(echo "$CREATE_RESP" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
79+
echo "创建会话:${SESSION_ID}"
80+
else
81+
SESSION_ID=$(echo "$SESSIONS" | grep -o '"id":"ses_[^"]*"' | head -1 | cut -d'"' -f4)
82+
echo "使用会话:${SESSION_ID}"
83+
fi
84+
echo ""
85+
86+
# 4. 检查会话状态
87+
echo -e "${YELLOW}[4/6] 检查会话状态...${NC}"
88+
STATUS_RESP=$(curl -s -u "opencode:${SERVER_PASSWORD}" "${BASE_URL}/session/status")
89+
echo "会话状态响应:"
90+
echo "$STATUS_RESP" | head -c 500
91+
echo ""
92+
93+
# 5. 测试消息提交(无响应模式)
94+
echo -e "${YELLOW}[5/6] 测试消息提交(no-reply 模式)...${NC}"
95+
MESSAGE_REQ='{
96+
"parts": [
97+
{
98+
"type": "text",
99+
"text": "这是一个测试消息,请回复 OK"'
100+
}
101+
],
102+
"noReply": true
103+
}'
104+
105+
MSG_RESP=$(curl -s -X POST -u "opencode:${SERVER_PASSWORD}" \
106+
-H "Content-Type: application/json" \
107+
-d "$MESSAGE_REQ" \
108+
"${BASE_URL}/session/${SESSION_ID}/message")
109+
110+
echo "消息提交响应:"
111+
echo "$MSG_RESP"
112+
113+
if echo "$MSG_RESP" | grep -q '"id"'; then
114+
MSG_ID=$(echo "$MSG_RESP" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
115+
echo -e "${GREEN}✓ 消息提交成功,ID: ${MSG_ID}${NC}"
116+
else
117+
echo -e "${RED}✗ 消息提交失败${NC}"
118+
echo "响应内容:$MSG_RESP"
119+
exit 1
120+
fi
121+
echo ""
122+
123+
# 6. 检查消息历史
124+
echo -e "${YELLOW}[6/6] 检查消息历史...${NC}"
125+
sleep 2 # 等待 2 秒让服务器处理
126+
127+
MSG_HISTORY=$(curl -s -u "opencode:${SERVER_PASSWORD}" \
128+
"${BASE_URL}/session/${SESSION_ID}/message?limit=5")
129+
130+
echo "最新消息历史:"
131+
echo "$MSG_HISTORY" | head -c 1000
132+
echo ""
133+
134+
# 检查是否有 AI 响应
135+
if echo "$MSG_HISTORY" | grep -q '"role":"assistant"'; then
136+
echo -e "${GREEN}✓ 检测到 AI 响应${NC}"
137+
else
138+
echo -e "${YELLOW}! 未检测到 AI 响应${NC}"
139+
echo ""
140+
echo "可能的原因:"
141+
echo " 1. AI 模型配置问题 - 检查 provider 配置"
142+
echo " 2. 会话被中止 - 检查会话状态"
143+
echo " 3. 权限请求等待确认 - 检查是否有权限弹窗"
144+
echo " 4. 服务器日志 - 查看 opencode serve 输出"
145+
fi
146+
echo ""
147+
148+
echo "========================================="
149+
echo "调试完成"
150+
echo "========================================="
151+
echo ""
152+
echo "建议的下一步:"
153+
echo "1. 检查 OpenCode 服务器日志:查看 opencode serve 的输出"
154+
echo "2. 检查提供商配置:oho config providers"
155+
echo "3. 检查会话权限:oho session permissions <session-id>"
156+
echo "4. 尝试使用 oho CLI: oho message add -s ${SESSION_ID} '测试' --no-reply"

0 commit comments

Comments
 (0)