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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sophhub",
3
- "version": "0.4.28",
3
+ "version": "0.4.30",
4
4
  "description": "SophHub CLI - Manage and download AI Agent skills and agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "agent-install",
3
- "version": "0.1.7",
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-20"
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.5",
3
+ "version": "1.0.7",
4
4
  "types": [
5
5
  "store"
6
6
  ],
7
7
  "displayName": "在线提Bug",
8
- "description": "用户说「在线提交bug」时收集 Bug 并经由虾友 DM 发送工单(含 session 附件)",
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-19"
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**」后,收集 Bug 描述并提交工单。
8
+ 用户说「**在线提交 Bug**」(`bug` 不区分大小写,允许中间空格)后执行。
11
9
 
12
- ## Processing Mode
10
+ ## Step 1:校验好友
13
11
 
14
- **STRICT SERIAL PROCESSING ONLY** — 单次顺序执行。
15
-
16
- ## Prerequisites
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
- ### Step 1:用户说「在线提交 Bug」
22
+ ## Step 2:收集描述
52
23
 
53
- Agent **立即停止任何尝试解决问题的行为**,回复:
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
- **上传完整的 `.jsonl` 文件**(包含整个对话历史)。
32
+ 记录用户原话。若描述不足追问「请问具体现象是什么?」
87
33
 
88
- ### Step 4:上传到 OSS
34
+ ## Step 3:提交工单
89
35
 
90
- ```bash
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
- cd {workspace}/skills/online-bug-report/src
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 "${SESSION_KEY}" \
105
- --oss-url "${OSS_URL}" \
41
+ --session-key "{sessionKey}" \
42
+ --agent-id "{agentId}" \
106
43
  --json
107
44
  ```
108
45
 
109
- ### Step 6:回复用户
110
-
111
- - 成功:「已提交 Bug 工单,会跟进处理。」
112
- - 失败:「已记录问题,稍后将补发工单。」
113
-
114
- ## 与「知识库反馈」分流
115
-
116
- | 用户意图 | 处理 |
117
- |---------|------|
118
- | 「文档错了」「知识库内容有误」 | `memory/feedback-*.md` 流程 |
119
- | 「在线提交 Bug」 | **本 Skill** → 收集并提交 |
120
-
121
- ## 安全约束
46
+ ## Step 4:回复用户
122
47
 
123
- - **不暴露**:JWT、凭证路径、friendId、API 地址
124
- - **不询问**:技术细节、配置参数
125
- - **不尝试**:分析或修复 Bug
48
+ - 退出码 0 → 「已提交 Bug 工单,会跟进处理。」
49
+ - 退出码非 0 → 「提交 Bug 失败,失败原因为:{stderr}」
126
50
 
127
51
  ## Forbidden
128
52
 
129
- - 不要尝试解决用户的问题
130
- - 不要向用户暴露 JWT、凭证
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.5"
3
+ version = "1.0.7"
4
4
  description = "Send VIP online bug reports to a Sophclaw friend via IM"
5
- requires-python = ">=3.10"
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
  }