sophhub 0.4.57 → 0.4.58
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,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-install",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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
|
+
"新增 resolve_new_instance.py:新建实例时确定生成下一个可用的 openclaw_id 和 workspace,不再依赖 LLM 手动生成"
|
|
13
|
+
],
|
|
14
|
+
"date": "2026-07-09",
|
|
15
|
+
"version": "0.1.13"
|
|
16
|
+
},
|
|
10
17
|
{
|
|
11
18
|
"changes": [
|
|
12
19
|
"新建实例时仅询问 agent_name,openclaw_id 和 workspace 按规则自动生成"
|
|
@@ -61,9 +61,15 @@ uv run {baseDir}/scripts/resolve_install_params.py \
|
|
|
61
61
|
|
|
62
62
|
确认 `openclaw_id`、`workspace`、`agent_name`。有 `placeholder_catalog` 时让用户确认替换文案,用户可覆盖默认值。
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
用户选择「新建实例」时,**仅询问 `agent_name`**(显示名称),`openclaw_id` 和 `workspace` 由脚本确定生成,不向用户索要:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
uv run {baseDir}/scripts/resolve_new_instance.py \
|
|
68
|
+
--agent-id "{agent_id}" \
|
|
69
|
+
--path "/home/node/.openclaw/workspace"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
取返回的 `openclaw_id`(形如 `{agent_id}-{N}`)和 `workspace`(实例 #1 workspace 末尾追加 `-{N}`),后续步骤按此传入 `--openclaw-id` / `--workspace`。
|
|
67
73
|
|
|
68
74
|
**2)按需替换 .md 中的占位符**(有 `placeholders` 时)
|
|
69
75
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""为「新建实例」确定性地生成下一个可用的 openclaw_id 和 workspace。
|
|
3
|
+
|
|
4
|
+
读取 openclaw.json,扫描 agents.list 中所有匹配 ^{agent_id}(-(\d+))?$ 的条目,
|
|
5
|
+
取最大编号 + 1 作为新实例编号,输出 openclaw_id 与 workspace。
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import json
|
|
11
|
+
import re
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from common import (
|
|
16
|
+
default_openclaw_config_path,
|
|
17
|
+
find_agent_entry,
|
|
18
|
+
load_agent_definition,
|
|
19
|
+
load_openclaw_config,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def next_instance_number(existing_ids: list[str], agent_id: str) -> int:
|
|
24
|
+
"""从已有 id 列表算出下一个实例编号。裸 agent_id 视为 1,agent_id-N 视为 N。"""
|
|
25
|
+
pattern = re.compile(rf"^{re.escape(agent_id)}(?:-(\d+))?$")
|
|
26
|
+
numbers: set[int] = set()
|
|
27
|
+
for eid in existing_ids:
|
|
28
|
+
if not isinstance(eid, str):
|
|
29
|
+
continue
|
|
30
|
+
match = pattern.fullmatch(eid)
|
|
31
|
+
if match is None:
|
|
32
|
+
continue
|
|
33
|
+
suffix = match.group(1)
|
|
34
|
+
numbers.add(int(suffix) if suffix else 1)
|
|
35
|
+
if not numbers:
|
|
36
|
+
return 2
|
|
37
|
+
return max(numbers) + 1
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def base_workspace_for(agent_id: str, agent_def: dict, config: dict) -> str:
|
|
41
|
+
"""实例 #1 的实际 workspace 作为新实例 workspace 的基。取不到则回退到 .config.json 的 workspace。"""
|
|
42
|
+
entry = find_agent_entry(config, agent_id)
|
|
43
|
+
if entry and isinstance(entry.get("workspace"), str) and entry["workspace"].strip():
|
|
44
|
+
return entry["workspace"].rstrip("/")
|
|
45
|
+
configured = agent_def.get("install", {}).get("workspace") or agent_def.get("workspace")
|
|
46
|
+
if isinstance(configured, str) and configured.strip():
|
|
47
|
+
return configured.rstrip("/")
|
|
48
|
+
return f"/home/node/.openclaw/workspace-{agent_id}"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def resolve_new_instance(agent_id: str, source_path: Path, config_path: Path) -> dict[str, object]:
|
|
52
|
+
agent_def = load_agent_definition(agent_id, source_path)
|
|
53
|
+
openclaw = load_openclaw_config(config_path)
|
|
54
|
+
agents_list = openclaw.get("agents", {}).get("list", []) or []
|
|
55
|
+
existing_ids = [a.get("id") for a in agents_list if isinstance(a, dict)]
|
|
56
|
+
|
|
57
|
+
next_n = next_instance_number(existing_ids, agent_id)
|
|
58
|
+
new_openclaw_id = f"{agent_id}-{next_n}"
|
|
59
|
+
base_ws = base_workspace_for(agent_id, agent_def, openclaw)
|
|
60
|
+
new_workspace = f"{base_ws}-{next_n}"
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
"ok": True,
|
|
64
|
+
"agent_id": agent_id,
|
|
65
|
+
"openclaw_id": new_openclaw_id,
|
|
66
|
+
"workspace": new_workspace,
|
|
67
|
+
"instance_number": next_n,
|
|
68
|
+
"message": f"新实例参数:openclaw_id={new_openclaw_id},workspace={new_workspace}",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main() -> int:
|
|
73
|
+
parser = argparse.ArgumentParser(description="为新建实例生成下一个可用的 openclaw_id 和 workspace")
|
|
74
|
+
parser.add_argument("--agent-id", required=True, help="Agent ID")
|
|
75
|
+
parser.add_argument("--path", required=True, help="Agent 下载目录(sophhub agent download 的 --path)")
|
|
76
|
+
parser.add_argument(
|
|
77
|
+
"--config",
|
|
78
|
+
default=str(default_openclaw_config_path()),
|
|
79
|
+
help="openclaw.json 路径",
|
|
80
|
+
)
|
|
81
|
+
args = parser.parse_args()
|
|
82
|
+
|
|
83
|
+
result = resolve_new_instance(
|
|
84
|
+
args.agent_id,
|
|
85
|
+
Path(args.path).expanduser().resolve(),
|
|
86
|
+
Path(args.config).expanduser().resolve(),
|
|
87
|
+
)
|
|
88
|
+
json.dump(result, sys.stdout, indent=2, ensure_ascii=False)
|
|
89
|
+
sys.stdout.write("\n")
|
|
90
|
+
return 0
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
if __name__ == "__main__":
|
|
94
|
+
raise SystemExit(main())
|