sophhub 0.4.2 → 0.4.3

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.
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ from common import load_json
10
+
11
+
12
+ REQUIRED_FILES = [
13
+ ".config.json",
14
+ "AGENTS.md",
15
+ "BOOTSTRAP.md",
16
+ "IDENTITY.md",
17
+ "SOUL.md",
18
+ "TOOLS.md",
19
+ "USER.md",
20
+ ]
21
+
22
+
23
+ def inspect_candidate(agent_id: str, directory: Path) -> dict[str, object]:
24
+ config_path = directory / ".config.json"
25
+ if not config_path.is_file():
26
+ return {
27
+ "directory": str(directory),
28
+ "ok": False,
29
+ "reason": "config_missing",
30
+ }
31
+
32
+ try:
33
+ config = load_json(config_path)
34
+ except Exception as exc: # noqa: BLE001
35
+ return {
36
+ "directory": str(directory),
37
+ "ok": False,
38
+ "reason": "config_invalid",
39
+ "error": str(exc),
40
+ }
41
+
42
+ config_agent_id = config.get("agent_id")
43
+ missing_files = [name for name in REQUIRED_FILES if not (directory / name).is_file()]
44
+ missing_fields = [name for name in ("agent_id", "version", "workspace", "agent_dependencies") if name not in config]
45
+
46
+ if config_agent_id != agent_id:
47
+ return {
48
+ "directory": str(directory),
49
+ "ok": False,
50
+ "reason": "agent_id_mismatch",
51
+ "config_agent_id": config_agent_id,
52
+ "missing_files": missing_files,
53
+ "missing_fields": missing_fields,
54
+ }
55
+
56
+ if missing_fields:
57
+ return {
58
+ "directory": str(directory),
59
+ "ok": False,
60
+ "reason": "config_fields_missing",
61
+ "config_agent_id": config_agent_id,
62
+ "missing_files": missing_files,
63
+ "missing_fields": missing_fields,
64
+ }
65
+
66
+ if missing_files:
67
+ return {
68
+ "directory": str(directory),
69
+ "ok": False,
70
+ "reason": "required_files_missing",
71
+ "config_agent_id": config_agent_id,
72
+ "missing_files": missing_files,
73
+ "missing_fields": missing_fields,
74
+ }
75
+
76
+ return {
77
+ "directory": str(directory),
78
+ "ok": True,
79
+ "reason": "valid",
80
+ "config_agent_id": config_agent_id,
81
+ "version": config.get("version"),
82
+ "workspace": config.get("workspace"),
83
+ "agent_dependencies": config.get("agent_dependencies", []),
84
+ "missing_files": [],
85
+ "missing_fields": [],
86
+ }
87
+
88
+
89
+ def candidate_directories(download_path: Path, agent_id: str) -> list[Path]:
90
+ candidates = [download_path / agent_id, download_path]
91
+ unique: list[Path] = []
92
+ seen: set[str] = set()
93
+ for candidate in candidates:
94
+ resolved = str(candidate)
95
+ if resolved not in seen:
96
+ unique.append(candidate)
97
+ seen.add(resolved)
98
+ return unique
99
+
100
+
101
+ def verify_download(agent_id: str, download_path: Path) -> dict[str, object]:
102
+ inspections = []
103
+ for directory in candidate_directories(download_path, agent_id):
104
+ inspections.append(inspect_candidate(agent_id, directory))
105
+
106
+ valid = next((item for item in inspections if item["ok"]), None)
107
+ if valid:
108
+ return {
109
+ "ok": True,
110
+ "agent_id": agent_id,
111
+ "download_path": str(download_path),
112
+ "agent_directory": valid["directory"],
113
+ "version": valid["version"],
114
+ "workspace": valid["workspace"],
115
+ "agent_dependencies": valid["agent_dependencies"],
116
+ "message": "Agent 下载成功,关键配置文件校验通过。",
117
+ "inspections": inspections,
118
+ }
119
+
120
+ first_error = inspections[0] if inspections else {"reason": "unknown"}
121
+ return {
122
+ "ok": False,
123
+ "agent_id": agent_id,
124
+ "download_path": str(download_path),
125
+ "message": "Agent 下载结果校验失败,请检查下载目录和 Agent 包内容。",
126
+ "reason": first_error.get("reason"),
127
+ "inspections": inspections,
128
+ }
129
+
130
+
131
+ def main() -> int:
132
+ parser = argparse.ArgumentParser(description="校验 Agent 下载结果")
133
+ parser.add_argument("--agent-id", required=True, help="Agent ID")
134
+ parser.add_argument(
135
+ "--path",
136
+ required=True,
137
+ help="sophhub agent download 使用的目标目录",
138
+ )
139
+ args = parser.parse_args()
140
+
141
+ result = verify_download(args.agent_id, Path(args.path).expanduser().resolve())
142
+ json.dump(result, sys.stdout, indent=2, ensure_ascii=False)
143
+ sys.stdout.write("\n")
144
+ return 0 if result["ok"] else 1
145
+
146
+
147
+ if __name__ == "__main__":
148
+ raise SystemExit(main())