sophhub 0.4.18 → 0.4.19
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/agents/intern-admin/.config.json +2 -1
- package/agents/intern-qa/.config.json +2 -1
- package/agents/parent-toddler/.config.json +3 -1
- package/package.json +1 -1
- package/skills/agent-install/skill.json +9 -2
- package/skills/agent-install/src/SKILL.md +3 -1
- package/skills/agent-install/src/pyproject.toml +1 -1
- package/skills/agent-install/src/scripts/common.py +91 -10
- package/skills/agent-install/src/scripts/update_openclaw.py +10 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.2.0",
|
|
3
3
|
"agent_id": "intern-admin",
|
|
4
4
|
"description": "实习事务管理员:维护实习相关 knowledge/、workspace-intern-qa/records/(日报按日、请假 leave.md),并配合配对实习生答疑实例",
|
|
5
|
+
"auto_generate_image_description": false,
|
|
5
6
|
"bot_api_enabled": false,
|
|
6
7
|
"workspace": "/home/node/.openclaw/workspace-intern",
|
|
7
8
|
"agent_dependencies": [],
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.2.0",
|
|
3
3
|
"agent_id": "intern-qa",
|
|
4
4
|
"description": "实习生助手 bot:只读 knowledge/ 答疑;日报按日追加 records/,请假单独 records/leave.md(解析公历日期);归档查询;memory/ 备忘;预装 image-description",
|
|
5
|
+
"auto_generate_image_description": false,
|
|
5
6
|
"bot_api_enabled": true,
|
|
6
7
|
"workspace": "/home/node/.openclaw/workspace-intern/workspace-intern-qa",
|
|
7
8
|
"agent_dependencies": ["intern-admin"],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.1.0",
|
|
3
3
|
"agent_id": "parent-toddler",
|
|
4
|
+
"agent_label": "幼儿家长助手",
|
|
4
5
|
"description": "面向幼儿家长的成长陪伴助手:亲子互动、图片与多媒体创作、日常记录与轻量咨询",
|
|
6
|
+
"auto_generate_image_description": false,
|
|
5
7
|
"bot_api_enabled": false,
|
|
6
8
|
"workspace": "/home/node/.openclaw/workspace-parent-toddler",
|
|
7
9
|
"agent_dependencies": [],
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-install",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"types": [
|
|
5
5
|
"store"
|
|
6
6
|
],
|
|
7
7
|
"displayName": "Agent安装",
|
|
8
8
|
"description": "通用 Agent 安装与升级。",
|
|
9
9
|
"changelog": [
|
|
10
|
+
{
|
|
11
|
+
"changes": [
|
|
12
|
+
"update_openclaw 根据 .config.json 的 auto_generate_image_description 同步自动生成图片描述开关(默认开启)"
|
|
13
|
+
],
|
|
14
|
+
"date": "2026-05-15",
|
|
15
|
+
"version": "0.1.5"
|
|
16
|
+
},
|
|
10
17
|
{
|
|
11
18
|
"changes": [
|
|
12
19
|
"修复依赖 Agent 使用自定义 openclaw_id 时的安装检测逻辑"
|
|
@@ -23,5 +30,5 @@
|
|
|
23
30
|
}
|
|
24
31
|
],
|
|
25
32
|
"createdAt": "2026-04-21",
|
|
26
|
-
"updatedAt": "2026-
|
|
33
|
+
"updatedAt": "2026-05-15"
|
|
27
34
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-install
|
|
3
3
|
description: 安装或升级通用 OpenClaw Agent(含按 .config.json 自动下载 skill)。Use when the user asks to install an agent, upgrade an agent, download agent config, back up an existing agent, update openclaw.json, or install skills listed with auto_install.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Agent Install
|
|
@@ -165,6 +165,8 @@ uv run {baseDir}/scripts/update_openclaw.py \
|
|
|
165
165
|
--name "{agent_name}"
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
**自动生成图片描述**:Agent 包 `.config.json` 顶层可选 **`auto_generate_image_description`**(布尔);不写或与 `true` 为开启,`false` 为关闭。与 **`update_openclaw.py`** 一并生效;具体写入 **`openclaw.json`** 的规则以实现为准,脚本标准输出中含 **`auto_generate_image_description`** 字段便于核对。
|
|
169
|
+
|
|
168
170
|
`NOT_INSTALLED` 无备份,直接 2)。`UPDATABLE` / `SAME_VERSION_REINSTALL` 须已完成 1)。
|
|
169
171
|
|
|
170
172
|
**输入模版(仅要备份时)**
|
|
@@ -231,16 +231,25 @@ def build_agent_entry(
|
|
|
231
231
|
) -> dict[str, Any]:
|
|
232
232
|
source_agent_id = agent_def["agent_id"]
|
|
233
233
|
agent_id = target_id_override.strip() if isinstance(target_id_override, str) and target_id_override.strip() else source_agent_id
|
|
234
|
-
install = agent_def.get("install", {})
|
|
235
|
-
identity = install.get("identity", {})
|
|
234
|
+
install = agent_def.get("install", {}) if isinstance(agent_def.get("install"), dict) else {}
|
|
235
|
+
identity = install.get("identity", {}) if isinstance(install.get("identity"), dict) else {}
|
|
236
236
|
resolved_name = name_override.strip() if isinstance(name_override, str) and name_override.strip() else None
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
install_name_raw = install.get("name")
|
|
239
|
+
install_name_str = install_name_raw.strip() if isinstance(install_name_raw, str) and install_name_raw.strip() else None
|
|
240
|
+
|
|
241
|
+
identity_name_raw = identity.get("name")
|
|
242
|
+
identity_name_str = identity_name_raw.strip() if isinstance(identity_name_raw, str) and identity_name_raw.strip() else None
|
|
243
|
+
|
|
244
|
+
agent_label_raw = agent_def.get("agent_label")
|
|
245
|
+
agent_label_str = agent_label_raw.strip() if isinstance(agent_label_raw, str) and agent_label_raw.strip() else None
|
|
246
|
+
|
|
247
|
+
display_name = resolved_name or install_name_str or identity_name_str or agent_label_str or source_agent_id
|
|
239
248
|
entry: dict[str, Any] = {
|
|
240
249
|
"id": agent_id,
|
|
241
250
|
"workspace": desired_workspace(agent_def, workspace_override),
|
|
242
251
|
"identity": {
|
|
243
|
-
"name": resolved_name or
|
|
252
|
+
"name": resolved_name or identity_name_str or agent_label_str or display_name,
|
|
244
253
|
"theme": identity.get("theme", display_name),
|
|
245
254
|
"emoji": identity.get("emoji", "🤖"),
|
|
246
255
|
},
|
|
@@ -248,8 +257,8 @@ def build_agent_entry(
|
|
|
248
257
|
|
|
249
258
|
if resolved_name:
|
|
250
259
|
entry["name"] = resolved_name
|
|
251
|
-
elif
|
|
252
|
-
entry["name"] =
|
|
260
|
+
elif install_name_str:
|
|
261
|
+
entry["name"] = install_name_str
|
|
253
262
|
|
|
254
263
|
if install.get("agent_dir"):
|
|
255
264
|
entry["agentDir"] = install["agent_dir"]
|
|
@@ -285,15 +294,20 @@ def build_bot_api_account(
|
|
|
285
294
|
if not agent_def.get("bot_api_enabled"):
|
|
286
295
|
return None
|
|
287
296
|
|
|
288
|
-
install = agent_def.get("install", {})
|
|
289
|
-
identity = install.get("identity", {})
|
|
290
|
-
bot_api = install.get("bot_api", {})
|
|
297
|
+
install = agent_def.get("install", {}) if isinstance(agent_def.get("install"), dict) else {}
|
|
298
|
+
identity = install.get("identity", {}) if isinstance(install.get("identity"), dict) else {}
|
|
299
|
+
bot_api = install.get("bot_api", {}) if isinstance(install.get("bot_api"), dict) else {}
|
|
291
300
|
resolved_name = name_override.strip() if isinstance(name_override, str) and name_override.strip() else None
|
|
292
301
|
|
|
302
|
+
identity_name_raw = identity.get("name")
|
|
303
|
+
identity_name_str = identity_name_raw.strip() if isinstance(identity_name_raw, str) and identity_name_raw.strip() else None
|
|
304
|
+
agent_label_raw = agent_def.get("agent_label")
|
|
305
|
+
agent_label_str = agent_label_raw.strip() if isinstance(agent_label_raw, str) and agent_label_raw.strip() else None
|
|
306
|
+
|
|
293
307
|
source_agent_id = agent_def["agent_id"]
|
|
294
308
|
agent_id = agent_id_override.strip() if isinstance(agent_id_override, str) and agent_id_override.strip() else source_agent_id
|
|
295
309
|
account_id = bot_api.get("account_id", agent_id)
|
|
296
|
-
account_name = bot_api.get("account_name") or resolved_name or
|
|
310
|
+
account_name = bot_api.get("account_name") or resolved_name or identity_name_str or agent_label_str or source_agent_id
|
|
297
311
|
enabled = bot_api.get("enabled", True)
|
|
298
312
|
|
|
299
313
|
return account_id, {
|
|
@@ -485,3 +499,70 @@ def deep_merge_dict(base: dict[str, Any], override: dict[str, Any]) -> dict[str,
|
|
|
485
499
|
else:
|
|
486
500
|
result[key] = deepcopy(value)
|
|
487
501
|
return result
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
def auto_generate_image_description_prefix(openclaw_agent_id: str) -> str:
|
|
505
|
+
"""与 openclaw.json 中 tools.media.image.scope.rules.match.keyPrefix 对齐。"""
|
|
506
|
+
aid = openclaw_agent_id.strip() if isinstance(openclaw_agent_id, str) else ""
|
|
507
|
+
return f"agent:{aid}:" if aid else ""
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def is_auto_generate_image_description_enabled(agent_def: dict[str, Any]) -> bool:
|
|
511
|
+
"""未设置或为真时启用自动生成图片描述;仅当显式为 false 时关闭。"""
|
|
512
|
+
raw = agent_def.get("auto_generate_image_description")
|
|
513
|
+
if raw is None:
|
|
514
|
+
return True
|
|
515
|
+
if isinstance(raw, bool):
|
|
516
|
+
return raw
|
|
517
|
+
return bool(raw)
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def _rule_is_auto_image_description_deny(rule: Any, key_prefix: str) -> bool:
|
|
521
|
+
if not isinstance(rule, dict):
|
|
522
|
+
return False
|
|
523
|
+
if rule.get("action") != "deny":
|
|
524
|
+
return False
|
|
525
|
+
match = rule.get("match")
|
|
526
|
+
if not isinstance(match, dict):
|
|
527
|
+
return False
|
|
528
|
+
return match.get("keyPrefix") == key_prefix
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def sync_openclaw_auto_image_description_rules(
|
|
532
|
+
config: dict[str, Any],
|
|
533
|
+
openclaw_agent_id: str,
|
|
534
|
+
*,
|
|
535
|
+
enabled: bool,
|
|
536
|
+
) -> None:
|
|
537
|
+
"""
|
|
538
|
+
同步根级 tools.media.image.scope.rules:
|
|
539
|
+
- enabled=True:移除本安装流程写入的 deny(keyPrefix agent:<id>:)
|
|
540
|
+
- enabled=False:确保存在对应 deny 规则(与产品侧「关闭自动生成图片描述」一致)
|
|
541
|
+
"""
|
|
542
|
+
key_prefix = auto_generate_image_description_prefix(openclaw_agent_id)
|
|
543
|
+
if not key_prefix:
|
|
544
|
+
return
|
|
545
|
+
|
|
546
|
+
tools = config.setdefault("tools", {})
|
|
547
|
+
media = tools.setdefault("media", {})
|
|
548
|
+
image = media.setdefault("image", {})
|
|
549
|
+
scope = image.setdefault("scope", {})
|
|
550
|
+
scope.setdefault("default", "allow")
|
|
551
|
+
rules_any = scope.setdefault("rules", [])
|
|
552
|
+
if not isinstance(rules_any, list):
|
|
553
|
+
scope["rules"] = []
|
|
554
|
+
rules_any = scope["rules"]
|
|
555
|
+
|
|
556
|
+
if enabled:
|
|
557
|
+
scope["rules"] = [r for r in rules_any if not _rule_is_auto_image_description_deny(r, key_prefix)]
|
|
558
|
+
return
|
|
559
|
+
|
|
560
|
+
if any(_rule_is_auto_image_description_deny(r, key_prefix) for r in rules_any):
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
rules_any.append(
|
|
564
|
+
{
|
|
565
|
+
"action": "deny",
|
|
566
|
+
"match": {"keyPrefix": key_prefix},
|
|
567
|
+
}
|
|
568
|
+
)
|
|
@@ -15,9 +15,11 @@ from common import (
|
|
|
15
15
|
find_agent_entry,
|
|
16
16
|
find_bot_api_accounts_by_agent_id,
|
|
17
17
|
find_agent_by_workspace,
|
|
18
|
+
is_auto_generate_image_description_enabled,
|
|
18
19
|
load_agent_definition,
|
|
19
20
|
load_openclaw_config,
|
|
20
21
|
resolve_existing_agent_entry,
|
|
22
|
+
sync_openclaw_auto_image_description_rules,
|
|
21
23
|
write_install_state,
|
|
22
24
|
)
|
|
23
25
|
|
|
@@ -125,6 +127,13 @@ def update_openclaw(
|
|
|
125
127
|
name_override=resolved_name,
|
|
126
128
|
)
|
|
127
129
|
|
|
130
|
+
auto_img_desc = is_auto_generate_image_description_enabled(agent_def)
|
|
131
|
+
sync_openclaw_auto_image_description_rules(
|
|
132
|
+
config,
|
|
133
|
+
target_agent_id,
|
|
134
|
+
enabled=auto_img_desc,
|
|
135
|
+
)
|
|
136
|
+
|
|
128
137
|
dump_json(config_path, config)
|
|
129
138
|
state_path = write_install_state(
|
|
130
139
|
config_path,
|
|
@@ -149,6 +158,7 @@ def update_openclaw(
|
|
|
149
158
|
"previous_workspace": previous.get("workspace") if previous else None,
|
|
150
159
|
"version": agent_def["version"],
|
|
151
160
|
"install_state": str(state_path),
|
|
161
|
+
"auto_generate_image_description": auto_img_desc,
|
|
152
162
|
}
|
|
153
163
|
|
|
154
164
|
|