sophhub 0.4.28 → 0.4.30
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/package.json +1 -1
- package/skills/agent-install/skill.json +9 -2
- package/skills/agent-install/src/scripts/update_openclaw.py +62 -0
- package/skills/online-bug-report/skill.json +27 -3
- package/skills/online-bug-report/src/SKILL.md +26 -102
- package/skills/online-bug-report/src/pyproject.toml +10 -2
- package/skills/online-bug-report/src/references/config.example.json +1 -4
- package/skills/online-bug-report/src/scripts/report_bug.py +202 -103
- package/skills/online-bug-report/src/secrets/bug-report.json +1 -4
- package/skills/sophnet-image-ocr/skill.json +15 -3
- package/skills/sophnet-image-ocr/src/SKILL.md +28 -125
- package/skills/sophnet-image-ocr/src/pyproject.toml +8 -2
- package/skills/sophnet-image-ocr/src/references/api-details.md +36 -0
- package/skills/sophnet-image-ocr/src/scripts/ocr.py +26 -2
- package/skills/sophnet-image-ocr/src/uv.lock +0 -234
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-install",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"types": [
|
|
5
5
|
"store"
|
|
6
6
|
],
|
|
7
7
|
"displayName": "Agent安装",
|
|
8
8
|
"description": "安装或升级 Sophclaw Agent(含占位替换、备份、post_install 脚本与自动安装 skill)。",
|
|
9
9
|
"changelog": [
|
|
10
|
+
{
|
|
11
|
+
"changes": [
|
|
12
|
+
"新增 _ensure_main_agent_in_list:单 Agent 模式下安装 Agent 时自动迁移 main Agent 至 agents.list,防止 session 丢失"
|
|
13
|
+
],
|
|
14
|
+
"date": "2026-05-27",
|
|
15
|
+
"version": "0.1.8"
|
|
16
|
+
},
|
|
10
17
|
{
|
|
11
18
|
"changes": [
|
|
12
19
|
"新增 run_post_install.py:安装时执行 .config.json 中 post_install 脚本",
|
|
@@ -47,5 +54,5 @@
|
|
|
47
54
|
}
|
|
48
55
|
],
|
|
49
56
|
"createdAt": "2026-04-21",
|
|
50
|
-
"updatedAt": "2026-05-
|
|
57
|
+
"updatedAt": "2026-05-27"
|
|
51
58
|
}
|
|
@@ -6,6 +6,8 @@ import json
|
|
|
6
6
|
import sys
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from copy import deepcopy
|
|
10
|
+
|
|
9
11
|
from common import (
|
|
10
12
|
build_agent_entry,
|
|
11
13
|
build_bot_api_account,
|
|
@@ -33,6 +35,64 @@ def normalized_override(value: str | None) -> str | None:
|
|
|
33
35
|
return None
|
|
34
36
|
|
|
35
37
|
|
|
38
|
+
def _ensure_main_agent_in_list(config: dict, config_path: Path) -> dict | None:
|
|
39
|
+
"""如果 openclaw.json 处于单 Agent 模式(agents.list 为空但默认 workspace 存在),
|
|
40
|
+
将 main Agent 迁移至 list 中,防止 install 后 session 丢失。
|
|
41
|
+
|
|
42
|
+
返回迁移信息 dict(含 migrated/agent_id/workspace),无需迁移时返回 None。
|
|
43
|
+
"""
|
|
44
|
+
agents = config.setdefault("agents", {})
|
|
45
|
+
agents_list = agents.setdefault("list", [])
|
|
46
|
+
|
|
47
|
+
# 已有 Agent 列表条目 → 已是多 Agent 模式,无需迁移
|
|
48
|
+
if agents_list:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
root_dir = config_path.parent
|
|
52
|
+
# 默认 workspace 路径为 openclaw.json 同级目录下的 workspace
|
|
53
|
+
default_workspace = root_dir / "workspace"
|
|
54
|
+
if not default_workspace.is_dir():
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
main_id = config.get("id", "main")
|
|
58
|
+
if not isinstance(main_id, str) or not main_id.strip():
|
|
59
|
+
main_id = "main"
|
|
60
|
+
main_id = main_id.strip()
|
|
61
|
+
|
|
62
|
+
# workspace:优先顶层 config.workspace,否则用默认路径
|
|
63
|
+
top_workspace = config.get("workspace")
|
|
64
|
+
workspace = str(top_workspace) if isinstance(top_workspace, str) and top_workspace.strip() else str(default_workspace)
|
|
65
|
+
entry: dict = {"id": main_id, "workspace": workspace}
|
|
66
|
+
|
|
67
|
+
# model:顶层 config.model 优先于 defaults.model(单 Agent 模式顶层可能含 fallbacks 等)
|
|
68
|
+
defaults = agents.get("defaults", {})
|
|
69
|
+
top_model = config.get("model")
|
|
70
|
+
if isinstance(top_model, dict):
|
|
71
|
+
entry["model"] = deepcopy(top_model)
|
|
72
|
+
elif isinstance(defaults.get("model"), dict):
|
|
73
|
+
entry["model"] = deepcopy(defaults["model"])
|
|
74
|
+
if isinstance(defaults.get("heartbeat"), dict):
|
|
75
|
+
entry["heartbeat"] = deepcopy(defaults["heartbeat"])
|
|
76
|
+
|
|
77
|
+
# identity:优先从顶层 config 取,否则用 main_id 构造默认值
|
|
78
|
+
if isinstance(config.get("identity"), dict):
|
|
79
|
+
entry["identity"] = deepcopy(config["identity"])
|
|
80
|
+
else:
|
|
81
|
+
entry["identity"] = {"name": main_id, "theme": main_id, "emoji": "🤖"}
|
|
82
|
+
|
|
83
|
+
if isinstance(config.get("name"), str) and config["name"].strip():
|
|
84
|
+
entry["name"] = config["name"].strip()
|
|
85
|
+
if isinstance(config.get("agentDir"), str) and config["agentDir"].strip():
|
|
86
|
+
entry["agentDir"] = config["agentDir"].strip()
|
|
87
|
+
if isinstance(config.get("tools"), dict):
|
|
88
|
+
entry["tools"] = deepcopy(config["tools"])
|
|
89
|
+
if isinstance(config.get("skills"), list):
|
|
90
|
+
entry["skills"] = deepcopy(config["skills"])
|
|
91
|
+
|
|
92
|
+
agents_list.insert(0, entry)
|
|
93
|
+
return {"migrated": True, "agent_id": main_id, "workspace": workspace}
|
|
94
|
+
|
|
95
|
+
|
|
36
96
|
def upsert_agent(config: dict, entry: dict) -> str:
|
|
37
97
|
config.setdefault("agents", {})
|
|
38
98
|
agents = config["agents"].setdefault("list", [])
|
|
@@ -103,6 +163,7 @@ def update_openclaw(
|
|
|
103
163
|
resolved_name = normalized_override(name_override)
|
|
104
164
|
agent_def = load_agent_definition(agent_id, source_path)
|
|
105
165
|
config = load_openclaw_config(config_path)
|
|
166
|
+
main_migration = _ensure_main_agent_in_list(config, config_path)
|
|
106
167
|
desired_workspace = resolved_workspace or agent_def.get("install", {}).get("workspace") or agent_def.get("workspace")
|
|
107
168
|
previous = resolve_existing_agent_entry(config_path, config, agent_id, desired_workspace)
|
|
108
169
|
if previous is None and resolved_openclaw_id:
|
|
@@ -164,6 +225,7 @@ def update_openclaw(
|
|
|
164
225
|
"auto_generate_image_description": auto_img_desc,
|
|
165
226
|
"heartbeat_configured": heartbeat_cfg is not None,
|
|
166
227
|
"heartbeat": heartbeat_cfg,
|
|
228
|
+
"main_migration": main_migration,
|
|
167
229
|
}
|
|
168
230
|
|
|
169
231
|
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "online-bug-report",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"types": [
|
|
5
5
|
"store"
|
|
6
6
|
],
|
|
7
7
|
"displayName": "在线提Bug",
|
|
8
|
-
"description": "
|
|
8
|
+
"description": "当用户说「在线提交bug」时,收集问题描述并通过虾友 DM 提交工单。",
|
|
9
9
|
"changelog": [
|
|
10
|
+
{
|
|
11
|
+
"changes": [
|
|
12
|
+
"新增 ensure-friend 子命令,add_friend.py 删除逻辑内置",
|
|
13
|
+
"新增 --agent-id 参数,sessions 路径改为 /agents/{agentId}/sessions/",
|
|
14
|
+
"消息格式重构为 flat ▎结构",
|
|
15
|
+
"支持 JWT 自动解析 sender(userId/name)",
|
|
16
|
+
"错误消息改为显示实际失败原因",
|
|
17
|
+
"pyproject.toml 对齐 sophnet-image-ocr(aliyun mirror、依赖声明)",
|
|
18
|
+
"SKILL.md 精简至 55 行",
|
|
19
|
+
"清理死代码、提取 resolve_api_base 去重"
|
|
20
|
+
],
|
|
21
|
+
"date": "2026-05-28",
|
|
22
|
+
"version": "1.0.7"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"changes": [
|
|
26
|
+
"移除对 sophnet-oss skill 的引用,上传脚本自包含",
|
|
27
|
+
"路径改为运行时格式({baseDir}/scripts/),去除 src/ 和 workspace",
|
|
28
|
+
"新增模板变量说明节,定义 sender_id、sender_name 等变量",
|
|
29
|
+
"Python 版本要求从 3.10+ 降为 3.8+"
|
|
30
|
+
],
|
|
31
|
+
"date": "2026-05-27",
|
|
32
|
+
"version": "1.0.6"
|
|
33
|
+
},
|
|
10
34
|
{
|
|
11
35
|
"changes": [
|
|
12
36
|
"凭证移至 src/secrets/bug-report.json,与 npm 打包仅含 src/ 对齐"
|
|
@@ -51,5 +75,5 @@
|
|
|
51
75
|
}
|
|
52
76
|
],
|
|
53
77
|
"createdAt": "2026-05-18",
|
|
54
|
-
"updatedAt": "2026-05-
|
|
78
|
+
"updatedAt": "2026-05-28"
|
|
55
79
|
}
|
|
@@ -1,131 +1,55 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: online-bug-report
|
|
3
|
-
description:
|
|
4
|
-
仅当用户说「在线提交bug」(大小写不敏感)时触发。收集 Bug 描述、上传 session .jsonl 到 OSS,
|
|
5
|
-
通过虾友 DM 发送工单。勿因「提 Bug」「报障」「系统坏了」等其它说法触发。
|
|
3
|
+
description: 当用户说「在线提交bug」时,收集问题描述并通过虾友 DM 提交工单。
|
|
6
4
|
---
|
|
7
5
|
|
|
8
6
|
# 在线提 Bug
|
|
9
7
|
|
|
10
|
-
用户说「**在线提交 Bug
|
|
8
|
+
用户说「**在线提交 Bug**」(`bug` 不区分大小写,允许中间空格)后执行。
|
|
11
9
|
|
|
12
|
-
##
|
|
10
|
+
## Step 1:校验好友
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- Python 3.10+、`uv`
|
|
19
|
-
- 有效 JWT:`/home/node/.openclaw/jwt.json`(字段 `web_jwt`)
|
|
20
|
-
- `exec` 工具可用
|
|
21
|
-
|
|
22
|
-
## 凭证文件
|
|
23
|
-
|
|
24
|
-
**内置凭证(随 skill 下发):** `{baseDir}/secrets/bug-report.json`,下载后可直接使用。修改收件人请直接编辑该文件,或使用 `--cred-file` 指定其它路径。
|
|
25
|
-
|
|
26
|
-
## 触发词
|
|
27
|
-
|
|
28
|
-
**唯一触发词**:「在线提交bug」(`bug` 不区分大小写;允许 `在线提交 bug` 中间有空格)
|
|
29
|
-
|
|
30
|
-
| 用户说的话 | 是否触发 |
|
|
31
|
-
|-----------|----------|
|
|
32
|
-
| 「在线提交bug」/「在线提交 Bug」 | ✅ 触发 |
|
|
33
|
-
| 「提 Bug」 | ❌ 不触发,正常回答 |
|
|
34
|
-
| 「报 Bug」 | ❌ 不触发,正常回答 |
|
|
35
|
-
| 「系统坏了」 | ❌ 不触发,正常回答 |
|
|
36
|
-
| 「有个 Bug」 | ❌ 不触发,正常回答 |
|
|
37
|
-
|
|
38
|
-
## Agent 角色定位
|
|
39
|
-
|
|
40
|
-
**Agent 是 Bug 信息收集者,不是问题解决者。**
|
|
41
|
-
|
|
42
|
-
| Agent 行为 | 正确/错误 |
|
|
43
|
-
|-----------|----------|
|
|
44
|
-
| 收集用户描述 → 提交工单 | ✅ 正确 |
|
|
45
|
-
| 尝试自己分析/修复 Bug | ❌ 错误 |
|
|
46
|
-
| 询问技术细节、API、配置 | ❌ 错误 |
|
|
47
|
-
| 让用户补充现象描述 | ✅ 正确 |
|
|
12
|
+
```bash
|
|
13
|
+
uv run {baseDir}/scripts/report_bug.py ensure-friend --json
|
|
14
|
+
```
|
|
48
15
|
|
|
49
|
-
|
|
16
|
+
| 退出码 | Agent 行为 |
|
|
17
|
+
|--------|-----------|
|
|
18
|
+
| 0 | 进入 Step 2 |
|
|
19
|
+
| 2 | 回复「研发值班还不是您的好友,已自动发送申请。通过后请重新提交 Bug」→ 结束 |
|
|
20
|
+
| 其他 | 回复「提交 Bug 失败,失败原因为:{stderr}」→ 结束 |
|
|
50
21
|
|
|
51
|
-
|
|
22
|
+
## Step 2:收集描述
|
|
52
23
|
|
|
53
|
-
|
|
24
|
+
回复以下内容让用户补充:
|
|
54
25
|
|
|
55
26
|
```
|
|
56
27
|
好的,我来帮您提交 Bug 工单。
|
|
57
28
|
|
|
58
|
-
|
|
59
|
-
- 具体是什么问题/现象?
|
|
60
|
-
- 大概什么时候发生的?
|
|
61
|
-
- 有复现步骤吗?(可选)
|
|
62
|
-
|
|
63
|
-
补充完之后告诉我,我会提交处理。
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**关键点**:
|
|
67
|
-
- **不尝试**:不分析原因、不尝试修复、不给解决方案
|
|
68
|
-
- **只收集**:等待用户补充描述
|
|
69
|
-
- **不询问技术细节**
|
|
70
|
-
|
|
71
|
-
### Step 2:等待用户补充描述
|
|
72
|
-
|
|
73
|
-
用户补充描述后,记录用户原话作为 Bug 描述。
|
|
74
|
-
|
|
75
|
-
若描述不足,追问:「请问具体现象是什么?」
|
|
76
|
-
不追问技术细节。
|
|
77
|
-
|
|
78
|
-
### Step 3:获取完整 session 文件
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
SESSION_KEY="{当前sessionKey}"
|
|
82
|
-
SESSION_ID=$(cat {agentDir}/sessions/sessions.json | jq -r '."${SESSION_KEY}".sessionId')
|
|
83
|
-
SESSION_FILE="{agentDir}/sessions/${SESSION_ID}.jsonl"
|
|
29
|
+
请补充一下您的具体问题/现象,如果能提供复现步骤,那更好。
|
|
84
30
|
```
|
|
85
31
|
|
|
86
|
-
|
|
32
|
+
记录用户原话。若描述不足追问「请问具体现象是什么?」
|
|
87
33
|
|
|
88
|
-
|
|
34
|
+
## Step 3:提交工单
|
|
89
35
|
|
|
90
|
-
|
|
91
|
-
cd {workspace}/skills/sophnet-oss
|
|
92
|
-
uv run --with sophnet-tools python scripts/upload_file.py \
|
|
93
|
-
--file "${SESSION_FILE}" --timeout 60
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Step 5:发送工单
|
|
36
|
+
获取当前 session 的 sessionKey 和 agentId(sessionKey 形如 `agent:<AgentID>:...`,取第二段即为 agentId),然后执行:
|
|
97
37
|
|
|
98
38
|
```bash
|
|
99
|
-
|
|
100
|
-
uv run scripts/report_bug.py send \
|
|
101
|
-
--sender-id "{sender_id}" \
|
|
102
|
-
--sender-name "{sender_name}" \
|
|
39
|
+
uv run {baseDir}/scripts/report_bug.py send \
|
|
103
40
|
--description "{用户完整描述}" \
|
|
104
|
-
--session-key "
|
|
105
|
-
--
|
|
41
|
+
--session-key "{sessionKey}" \
|
|
42
|
+
--agent-id "{agentId}" \
|
|
106
43
|
--json
|
|
107
44
|
```
|
|
108
45
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- 成功:「已提交 Bug 工单,会跟进处理。」
|
|
112
|
-
- 失败:「已记录问题,稍后将补发工单。」
|
|
113
|
-
|
|
114
|
-
## 与「知识库反馈」分流
|
|
115
|
-
|
|
116
|
-
| 用户意图 | 处理 |
|
|
117
|
-
|---------|------|
|
|
118
|
-
| 「文档错了」「知识库内容有误」 | `memory/feedback-*.md` 流程 |
|
|
119
|
-
| 「在线提交 Bug」 | **本 Skill** → 收集并提交 |
|
|
120
|
-
|
|
121
|
-
## 安全约束
|
|
46
|
+
## Step 4:回复用户
|
|
122
47
|
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
- **不尝试**:分析或修复 Bug
|
|
48
|
+
- 退出码 0 → 「已提交 Bug 工单,会跟进处理。」
|
|
49
|
+
- 退出码非 0 → 「提交 Bug 失败,失败原因为:{stderr}」
|
|
126
50
|
|
|
127
51
|
## Forbidden
|
|
128
52
|
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
53
|
+
- 不要分析/修复 Bug,只收集信息
|
|
54
|
+
- 不要询问技术细节、API、配置
|
|
55
|
+
- 不要暴露 JWT、凭证、friendId、API 地址
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "online-bug-report"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.7"
|
|
4
4
|
description = "Send VIP online bug reports to a Sophclaw friend via IM"
|
|
5
|
-
requires-python = ">=3.
|
|
5
|
+
requires-python = ">=3.8"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"requests>=2.28.0",
|
|
8
|
+
"sophnet-tools>=0.0.1",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[[tool.uv.index]]
|
|
12
|
+
url = "https://mirrors.aliyun.com/pypi/simple/"
|
|
13
|
+
default = true
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "字段说明参考;实际凭证见 secrets/bug-report.json(与 SKILL.md 同级的 src/secrets/)",
|
|
3
3
|
"dev_friend_id": 0,
|
|
4
|
-
"dev_friend_name": "收件人名称",
|
|
5
|
-
"terminal_label": "虾友 DM",
|
|
6
4
|
"terminal_url": "",
|
|
7
5
|
"session_url_template": "{base_url}/chat?session={session_key}",
|
|
8
6
|
"api_base_url": "https://yagent.sophnet.com/api",
|
|
9
|
-
"openclaw_base_url": ""
|
|
10
|
-
"default_model": "Qwen3.5-122B-A10B"
|
|
7
|
+
"openclaw_base_url": ""
|
|
11
8
|
}
|