8900 commited on
Commit
e9ebcd0
·
verified ·
1 Parent(s): e598666

Update hf-sync-manager.mjs

Browse files
Files changed (1) hide show
  1. hf-sync-manager.mjs +92 -78
hf-sync-manager.mjs CHANGED
@@ -9,7 +9,7 @@
9
  // SOUL.md <- persona / tone
10
  // USER.md <- user profile
11
  // IDENTITY.md <- name / emoji
12
- // TOOLS.md <- env conventions
13
  // HEARTBEAT.md <- periodic tasks
14
  // MEMORY.md <- long-term memory (iron rules)
15
  // memory/YYYY-MM-DD.md <- daily logs
@@ -37,7 +37,8 @@
37
  // Never downloads during runtime (prevents memory flooding)
38
  //
39
  // Multi-bot:
40
- // Set OPENCLAW_PROFILE env var in HF Space Variables.
 
41
  // OpenClaw uses ~/.openclaw/workspace-<profile>/ per profile.
42
  // Repo stores each profile under workspace-<profile>/.
43
  // ============================================================
@@ -54,14 +55,27 @@ var HF_TOKEN = (process.env.HF_TOKEN || "").trim();
54
  var DATASET_ID = (process.env.HF_DATASET_ID || "").trim();
55
  var REPO_DIR = "/tmp/hf-memory-sync";
56
 
57
- // OPENCLAW_PROFILE: if set, workspace is ~/.openclaw/workspace-<profile>/
58
- // This is OpenClaw's native multi-bot mechanism
59
- var PROFILE = (process.env.OPENCLAW_PROFILE || "").trim();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  var WORKSPACE_DIR = PROFILE
61
- ? path.join(OPENCLAW_DIR, "workspace-" + PROFILE)
62
- : path.join(OPENCLAW_DIR, "workspace");
63
 
64
- // Repo folder name for this profile's workspace
65
  var REPO_WORKSPACE_FOLDER = PROFILE ? "workspace-" + PROFILE : "workspace";
66
 
67
  var UPLOAD_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours
@@ -92,100 +106,100 @@ var NEVER_SYNC = [
92
  // -- helpers ----------------------------------
93
 
94
  function log(msg) {
95
- console.log("[hf-sync] " + msg);
96
  }
97
 
98
  function sleep(ms) {
99
- return new Promise(function(resolve) { setTimeout(resolve, ms); });
100
  }
101
 
102
  function repoUrl() {
103
- return "https://user:" + HF_TOKEN +
104
- "@huggingface.co/datasets/" + DATASET_ID;
105
  }
106
 
107
  function git(args) {
108
- return execSync("git " + args, {
109
- cwd: REPO_DIR,
110
- stdio: "pipe",
111
- timeout: 120000,
112
- env: Object.assign({}, process.env, { GIT_TERMINAL_PROMPT: "0" })
113
- }).toString().trim();
114
  }
115
 
116
  function isValidJson(filePath) {
117
- try {
118
- if (!fs.existsSync(filePath)) return false;
119
- var content = fs.readFileSync(filePath, "utf-8").trim();
120
- if (!content) return false;
121
- JSON.parse(content);
122
- return true;
123
- } catch (e) {
124
- return false;
125
- }
126
  }
127
 
128
  function copyItem(src, dst) {
129
- if (fs.statSync(src).isDirectory()) {
130
- execSync("cp -a " + src + " " + dst, { stdio: "pipe" });
131
- } else {
132
- fs.mkdirSync(path.dirname(dst), { recursive: true });
133
- fs.copyFileSync(src, dst);
134
- }
135
  }
136
 
137
  // -- git repo setup --------------------------
138
 
139
  function ensureRepo() {
140
- if (fs.existsSync(path.join(REPO_DIR, ".git"))) return;
141
- execSync("rm -rf " + REPO_DIR, { stdio: "pipe" });
142
- try {
143
- execSync(
144
- "git clone --depth 1 " + repoUrl() + " " + REPO_DIR,
145
- {
146
- stdio: "pipe",
147
- timeout: 120000,
148
- env: Object.assign({}, process.env, { GIT_TERMINAL_PROMPT: "0" })
149
- }
150
- );
151
- } catch (e) {
152
- fs.mkdirSync(REPO_DIR, { recursive: true });
153
- execSync("git init " + REPO_DIR, { stdio: "pipe" });
154
- git("remote add origin " + repoUrl());
155
- }
156
- try {
157
- git("config user.email openclaw@hf.space");
158
- git("config user.name OpenClaw-Sync");
159
- git("config pull.rebase false");
160
- } catch (e) { /* non-fatal */ }
161
  }
162
 
163
  function pullLatest() {
164
- try { git("fetch --quiet origin"); } catch (e) { /* ignore */ }
165
- try {
166
- git("pull --quiet --no-rebase origin main");
167
- } catch (e) {
168
- try { git("pull --quiet --no-rebase origin master"); } catch (e2) { /* no remote yet */ }
169
- }
170
  }
171
 
172
  function commitAndPush(label) {
173
- try {
174
- git("add -A");
175
- var changed = git("diff --cached --name-only");
176
- if (!changed) return 0;
177
- var count = changed.split("\n").filter(Boolean).length;
178
- var ts = new Date().toISOString().replace("T", " ").substring(0, 19);
179
- var tag = PROFILE ? "[" + PROFILE + "]" : "";
180
- git("commit -m \"sync" + tag + " " + ts + "\"");
181
- try {
182
- git("push --quiet origin HEAD:main");
183
- } catch (e) {
184
- git("push --quiet origin HEAD:master");
185
- }
186
- return count;
187
- } catch (e) {
188
- log("Commit/push failed: " + e.message);
189
- return 0;
190
- }
191
  }
 
9
  // SOUL.md <- persona / tone
10
  // USER.md <- user profile
11
  // IDENTITY.md <- name / emoji
12
+ // TOOLS.md <- env conventions
13
  // HEARTBEAT.md <- periodic tasks
14
  // MEMORY.md <- long-term memory (iron rules)
15
  // memory/YYYY-MM-DD.md <- daily logs
 
37
  // Never downloads during runtime (prevents memory flooding)
38
  //
39
  // Multi-bot:
40
+ // Set BOT1_PROFILE / BOT2_PROFILE / BOT3_PROFILE ... in HF Space Variables.
41
+ // The script will automatically use the first defined BOTx_PROFILE as OPENCLAW_PROFILE.
42
  // OpenClaw uses ~/.openclaw/workspace-<profile>/ per profile.
43
  // Repo stores each profile under workspace-<profile>/.
44
  // ============================================================
 
55
  var DATASET_ID = (process.env.HF_DATASET_ID || "").trim();
56
  var REPO_DIR = "/tmp/hf-memory-sync";
57
 
58
+ // --- Multi-bot support ----------------------
59
+ // Automatically detect BOTx_PROFILE from HF Variables
60
+ var PROFILE = "";
61
+ for (let i = 1; i <= 10; i++) { // 支持最多 10 个 bot,可自由扩展
62
+ let envVar = process.env[`BOT${i}_PROFILE`];
63
+ if (envVar && envVar.trim()) {
64
+ PROFILE = envVar.trim();
65
+ break; // 取第一个存在的 BOTx_PROFILE
66
+ }
67
+ }
68
+
69
+ // OPENCLAW_PROFILE fallback (legacy)
70
+ if (!PROFILE) {
71
+ PROFILE = (process.env.OPENCLAW_PROFILE || "").trim();
72
+ }
73
+
74
+ // Compute workspace dirs
75
  var WORKSPACE_DIR = PROFILE
76
+ ? path.join(OPENCLAW_DIR, "workspace-" + PROFILE)
77
+ : path.join(OPENCLAW_DIR, "workspace");
78
 
 
79
  var REPO_WORKSPACE_FOLDER = PROFILE ? "workspace-" + PROFILE : "workspace";
80
 
81
  var UPLOAD_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours
 
106
  // -- helpers ----------------------------------
107
 
108
  function log(msg) {
109
+ console.log("[hf-sync] " + msg);
110
  }
111
 
112
  function sleep(ms) {
113
+ return new Promise(function(resolve) { setTimeout(resolve, ms); });
114
  }
115
 
116
  function repoUrl() {
117
+ return "https://user:" + HF_TOKEN +
118
+ "@huggingface.co/datasets/" + DATASET_ID;
119
  }
120
 
121
  function git(args) {
122
+ return execSync("git " + args, {
123
+ cwd: REPO_DIR,
124
+ stdio: "pipe",
125
+ timeout: 120000,
126
+ env: Object.assign({}, process.env, { GIT_TERMINAL_PROMPT: "0" })
127
+ }).toString().trim();
128
  }
129
 
130
  function isValidJson(filePath) {
131
+ try {
132
+ if (!fs.existsSync(filePath)) return false;
133
+ var content = fs.readFileSync(filePath, "utf-8").trim();
134
+ if (!content) return false;
135
+ JSON.parse(content);
136
+ return true;
137
+ } catch (e) {
138
+ return false;
139
+ }
140
  }
141
 
142
  function copyItem(src, dst) {
143
+ if (fs.statSync(src).isDirectory()) {
144
+ execSync("cp -a " + src + " " + dst, { stdio: "pipe" });
145
+ } else {
146
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
147
+ fs.copyFileSync(src, dst);
148
+ }
149
  }
150
 
151
  // -- git repo setup --------------------------
152
 
153
  function ensureRepo() {
154
+ if (fs.existsSync(path.join(REPO_DIR, ".git"))) return;
155
+ execSync("rm -rf " + REPO_DIR, { stdio: "pipe" });
156
+ try {
157
+ execSync(
158
+ "git clone --depth 1 " + repoUrl() + " " + REPO_DIR,
159
+ {
160
+ stdio: "pipe",
161
+ timeout: 120000,
162
+ env: Object.assign({}, process.env, { GIT_TERMINAL_PROMPT: "0" })
163
+ }
164
+ );
165
+ } catch (e) {
166
+ fs.mkdirSync(REPO_DIR, { recursive: true });
167
+ execSync("git init " + REPO_DIR, { stdio: "pipe" });
168
+ git("remote add origin " + repoUrl());
169
+ }
170
+ try {
171
+ git("config user.email openclaw@hf.space");
172
+ git("config user.name OpenClaw-Sync");
173
+ git("config pull.rebase false");
174
+ } catch (e) { /* non-fatal */ }
175
  }
176
 
177
  function pullLatest() {
178
+ try { git("fetch --quiet origin"); } catch (e) { /* ignore */ }
179
+ try {
180
+ git("pull --quiet --no-rebase origin main");
181
+ } catch (e) {
182
+ try { git("pull --quiet --no-rebase origin master"); } catch (e2) { /* no remote yet */ }
183
+ }
184
  }
185
 
186
  function commitAndPush(label) {
187
+ try {
188
+ git("add -A");
189
+ var changed = git("diff --cached --name-only");
190
+ if (!changed) return 0;
191
+ var count = changed.split("\n").filter(Boolean).length;
192
+ var ts = new Date().toISOString().replace("T", " ").substring(0, 19);
193
+ var tag = PROFILE ? "[" + PROFILE + "]" : "";
194
+ git("commit -m \"sync" + tag + " " + ts + "\"");
195
+ try {
196
+ git("push --quiet origin HEAD:main");
197
+ } catch (e) {
198
+ git("push --quiet origin HEAD:master");
199
+ }
200
+ return count;
201
+ } catch (e) {
202
+ log("Commit/push failed: " + e.message);
203
+ return 0;
204
+ }
205
  }