@openclawcity/become 1.0.1 → 1.0.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.
- package/README.md +25 -3
- package/dist/cli.cjs +216 -94
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +210 -88
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -53,6 +53,157 @@ var LLM_DEFAULTS = {
|
|
|
53
53
|
openrouter: { base_url: "https://openrouter.ai/api" }
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
// src/cli/adapter/openclaw.ts
|
|
57
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
58
|
+
import { join as join2 } from "path";
|
|
59
|
+
import { homedir as homedir2 } from "os";
|
|
60
|
+
import { execSync } from "child_process";
|
|
61
|
+
var OPENCLAW_CONFIG = join2(homedir2(), ".openclaw", "openclaw.json");
|
|
62
|
+
var BACKUP_PATH = join2(homedir2(), ".become", "state", "original_openclaw.json");
|
|
63
|
+
var ORIGINAL_MODEL_PATH = join2(homedir2(), ".become", "state", "original_model.txt");
|
|
64
|
+
var PATCHED_AGENT_PATH = join2(homedir2(), ".become", "state", "patched_agent.txt");
|
|
65
|
+
function patchOpenClaw(config, agentId) {
|
|
66
|
+
if (!existsSync2(OPENCLAW_CONFIG)) {
|
|
67
|
+
throw new Error(`OpenClaw config not found at ${OPENCLAW_CONFIG}`);
|
|
68
|
+
}
|
|
69
|
+
const raw = readFileSync2(OPENCLAW_CONFIG, "utf-8");
|
|
70
|
+
const clawConfig = parseOpenClawConfig(raw);
|
|
71
|
+
if (clawConfig.models?.providers?.become) {
|
|
72
|
+
console.log("become is already connected. Run `become off` first to disconnect.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
mkdirSync2(join2(homedir2(), ".become", "state"), { recursive: true });
|
|
76
|
+
writeFileSync2(BACKUP_PATH, raw, "utf-8");
|
|
77
|
+
const agents = clawConfig.agents?.list ?? [];
|
|
78
|
+
let originalModel;
|
|
79
|
+
let patchedAgentId;
|
|
80
|
+
if (agents.length > 0 && agentId) {
|
|
81
|
+
const agent = agents.find((a) => a.id === agentId);
|
|
82
|
+
if (!agent) {
|
|
83
|
+
throw new Error(`Agent "${agentId}" not found in agents.list. Available: ${agents.map((a) => a.id).join(", ")}`);
|
|
84
|
+
}
|
|
85
|
+
originalModel = agent.model ?? clawConfig.agents?.defaults?.model?.primary ?? "";
|
|
86
|
+
patchedAgentId = agentId;
|
|
87
|
+
const modelId2 = stripProvider(originalModel);
|
|
88
|
+
if (!modelId2) {
|
|
89
|
+
throw new Error("No model configured for this agent. Set a model in openclaw.json first.");
|
|
90
|
+
}
|
|
91
|
+
agent.model = `become/${modelId2}`;
|
|
92
|
+
} else {
|
|
93
|
+
originalModel = clawConfig.agents?.defaults?.model?.primary ?? "";
|
|
94
|
+
patchedAgentId = "_defaults";
|
|
95
|
+
const modelId2 = stripProvider(originalModel);
|
|
96
|
+
if (!modelId2) {
|
|
97
|
+
throw new Error("No default model configured. Set agents.defaults.model.primary in openclaw.json first.");
|
|
98
|
+
}
|
|
99
|
+
if (!clawConfig.agents) clawConfig.agents = {};
|
|
100
|
+
if (!clawConfig.agents.defaults) clawConfig.agents.defaults = {};
|
|
101
|
+
if (!clawConfig.agents.defaults.model) clawConfig.agents.defaults.model = {};
|
|
102
|
+
clawConfig.agents.defaults.model.primary = `become/${modelId2}`;
|
|
103
|
+
}
|
|
104
|
+
writeFileSync2(ORIGINAL_MODEL_PATH, originalModel, "utf-8");
|
|
105
|
+
writeFileSync2(PATCHED_AGENT_PATH, patchedAgentId, "utf-8");
|
|
106
|
+
const modelId = stripProvider(originalModel);
|
|
107
|
+
if (!clawConfig.models) clawConfig.models = {};
|
|
108
|
+
if (!clawConfig.models.providers) clawConfig.models.providers = {};
|
|
109
|
+
clawConfig.models.providers.become = {
|
|
110
|
+
api: config.llm_provider === "openai" || config.llm_provider === "openrouter" ? "openai-completions" : "anthropic-messages",
|
|
111
|
+
baseUrl: `http://127.0.0.1:${config.proxy_port}`,
|
|
112
|
+
apiKey: config.llm_api_key,
|
|
113
|
+
models: [
|
|
114
|
+
{ id: modelId, name: `${modelId} via become` }
|
|
115
|
+
]
|
|
116
|
+
};
|
|
117
|
+
writeFileSync2(OPENCLAW_CONFIG, JSON.stringify(clawConfig, null, 2), "utf-8");
|
|
118
|
+
try {
|
|
119
|
+
execSync("openclaw gateway restart", { stdio: "pipe", timeout: 15e3 });
|
|
120
|
+
} catch {
|
|
121
|
+
console.log("Warning: Could not restart OpenClaw gateway. Restart it manually: openclaw gateway restart");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function restoreOpenClaw() {
|
|
125
|
+
if (!existsSync2(OPENCLAW_CONFIG)) {
|
|
126
|
+
throw new Error(`OpenClaw config not found at ${OPENCLAW_CONFIG}`);
|
|
127
|
+
}
|
|
128
|
+
if (existsSync2(BACKUP_PATH)) {
|
|
129
|
+
const backup = readFileSync2(BACKUP_PATH, "utf-8");
|
|
130
|
+
const backupConfig = parseOpenClawConfig(backup);
|
|
131
|
+
if (!backupConfig.models?.providers?.become) {
|
|
132
|
+
writeFileSync2(OPENCLAW_CONFIG, backup, "utf-8");
|
|
133
|
+
restartGateway();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const raw = readFileSync2(OPENCLAW_CONFIG, "utf-8");
|
|
138
|
+
const config = parseOpenClawConfig(raw);
|
|
139
|
+
const patchedAgentId = readStateFile(PATCHED_AGENT_PATH);
|
|
140
|
+
const originalModel = readStateFile(ORIGINAL_MODEL_PATH);
|
|
141
|
+
if (originalModel) {
|
|
142
|
+
const agents = config.agents?.list ?? [];
|
|
143
|
+
if (patchedAgentId && patchedAgentId !== "_defaults") {
|
|
144
|
+
const agent = agents.find((a) => a.id === patchedAgentId);
|
|
145
|
+
if (agent) {
|
|
146
|
+
agent.model = originalModel;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
if (config.agents?.defaults?.model) {
|
|
150
|
+
config.agents.defaults.model.primary = originalModel;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (config.models?.providers?.become) {
|
|
155
|
+
delete config.models.providers.become;
|
|
156
|
+
}
|
|
157
|
+
for (const provider of Object.values(config.models?.providers ?? {})) {
|
|
158
|
+
if (provider && typeof provider === "object" && "_originalModel" in provider) {
|
|
159
|
+
delete provider._originalModel;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
writeFileSync2(OPENCLAW_CONFIG, JSON.stringify(config, null, 2), "utf-8");
|
|
163
|
+
restartGateway();
|
|
164
|
+
}
|
|
165
|
+
function listOpenClawAgents() {
|
|
166
|
+
if (!existsSync2(OPENCLAW_CONFIG)) return [];
|
|
167
|
+
try {
|
|
168
|
+
const config = parseOpenClawConfig(readFileSync2(OPENCLAW_CONFIG, "utf-8"));
|
|
169
|
+
const agents = config.agents?.list ?? [];
|
|
170
|
+
const defaultModel = unbecome(config.agents?.defaults?.model?.primary ?? "unknown");
|
|
171
|
+
if (agents.length === 0) {
|
|
172
|
+
return [{ id: "_defaults", model: defaultModel }];
|
|
173
|
+
}
|
|
174
|
+
return agents.map((a) => ({
|
|
175
|
+
id: a.id,
|
|
176
|
+
model: unbecome(a.model ?? defaultModel)
|
|
177
|
+
}));
|
|
178
|
+
} catch {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function stripProvider(model) {
|
|
183
|
+
return model.includes("/") ? model.split("/").slice(1).join("/") : model;
|
|
184
|
+
}
|
|
185
|
+
function unbecome(model) {
|
|
186
|
+
return model.startsWith("become/") ? model.replace("become/", "") : model;
|
|
187
|
+
}
|
|
188
|
+
function parseOpenClawConfig(raw) {
|
|
189
|
+
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/,\s*([\]}])/g, "$1");
|
|
190
|
+
return JSON.parse(stripped);
|
|
191
|
+
}
|
|
192
|
+
function readStateFile(path) {
|
|
193
|
+
try {
|
|
194
|
+
return existsSync2(path) ? readFileSync2(path, "utf-8").trim() : "";
|
|
195
|
+
} catch {
|
|
196
|
+
return "";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function restartGateway() {
|
|
200
|
+
try {
|
|
201
|
+
execSync("openclaw gateway restart", { stdio: "pipe", timeout: 15e3 });
|
|
202
|
+
} catch {
|
|
203
|
+
console.log("Warning: Could not restart OpenClaw gateway. Restart it manually: openclaw gateway restart");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
56
207
|
// src/cli/setup.ts
|
|
57
208
|
var AGENT_TYPES = ["openclaw", "ironclaw", "nanoclaw", "generic"];
|
|
58
209
|
var LLM_PROVIDERS = ["anthropic", "openai", "ollama", "openrouter", "custom"];
|
|
@@ -68,7 +219,25 @@ async function runSetup() {
|
|
|
68
219
|
const agentChoice = await ask(rl, "> ");
|
|
69
220
|
const agentIdx = parseInt(agentChoice, 10) - 1;
|
|
70
221
|
const agent_type = AGENT_TYPES[agentIdx] ?? "openclaw";
|
|
71
|
-
|
|
222
|
+
let openclaw_agent_id;
|
|
223
|
+
if (agent_type === "openclaw") {
|
|
224
|
+
const agents = listOpenClawAgents();
|
|
225
|
+
if (agents.length > 1) {
|
|
226
|
+
console.log("\nWhich OpenClaw agent should learn from other agents?");
|
|
227
|
+
agents.forEach((a, i) => console.log(` ${i + 1}. ${a.id} (${a.model})`));
|
|
228
|
+
const agentPick = await ask(rl, "> ");
|
|
229
|
+
const pickIdx = parseInt(agentPick, 10) - 1;
|
|
230
|
+
const picked = agents[pickIdx];
|
|
231
|
+
if (picked && picked.id !== "_defaults") {
|
|
232
|
+
openclaw_agent_id = picked.id;
|
|
233
|
+
}
|
|
234
|
+
} else if (agents.length === 1 && agents[0].id !== "_defaults") {
|
|
235
|
+
openclaw_agent_id = agents[0].id;
|
|
236
|
+
console.log(`
|
|
237
|
+
OpenClaw agent: ${openclaw_agent_id} (${agents[0].model})`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
console.log("\nWhich LLM provider does your agent use?");
|
|
72
241
|
LLM_PROVIDERS.forEach((p, i) => console.log(` ${i + 1}. ${p}`));
|
|
73
242
|
const llmChoice = await ask(rl, "> ");
|
|
74
243
|
const llmIdx = parseInt(llmChoice, 10) - 1;
|
|
@@ -90,6 +259,7 @@ Proxy port (default 30001): `);
|
|
|
90
259
|
const dashboard_port = parseInt(dashInput, 10) || 30002;
|
|
91
260
|
const config = {
|
|
92
261
|
agent_type,
|
|
262
|
+
openclaw_agent_id,
|
|
93
263
|
llm_provider,
|
|
94
264
|
llm_base_url,
|
|
95
265
|
llm_api_key: llm_api_key.trim(),
|
|
@@ -113,20 +283,20 @@ Proxy port (default 30001): `);
|
|
|
113
283
|
import { createServer } from "http";
|
|
114
284
|
|
|
115
285
|
// src/skills/store.ts
|
|
116
|
-
import { readFileSync as
|
|
117
|
-
import { join as
|
|
286
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, readdirSync, mkdirSync as mkdirSync3, renameSync, unlinkSync, existsSync as existsSync3 } from "fs";
|
|
287
|
+
import { join as join3, basename } from "path";
|
|
118
288
|
import { createHash } from "crypto";
|
|
119
289
|
var FileSkillStore = class {
|
|
120
290
|
skillsDir;
|
|
121
291
|
pendingDir;
|
|
122
292
|
rejectedDir;
|
|
123
293
|
constructor(config) {
|
|
124
|
-
this.skillsDir =
|
|
125
|
-
this.pendingDir =
|
|
126
|
-
this.rejectedDir =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
294
|
+
this.skillsDir = join3(config.baseDir, "skills");
|
|
295
|
+
this.pendingDir = join3(config.baseDir, "pending");
|
|
296
|
+
this.rejectedDir = join3(config.baseDir, "rejected");
|
|
297
|
+
mkdirSync3(this.skillsDir, { recursive: true });
|
|
298
|
+
mkdirSync3(this.pendingDir, { recursive: true });
|
|
299
|
+
mkdirSync3(this.rejectedDir, { recursive: true });
|
|
130
300
|
}
|
|
131
301
|
// ── Read ────────────────────────────────────────────────────────────────
|
|
132
302
|
listApproved() {
|
|
@@ -140,7 +310,7 @@ var FileSkillStore = class {
|
|
|
140
310
|
}
|
|
141
311
|
getApproved(id) {
|
|
142
312
|
this.validateId(id);
|
|
143
|
-
return this.readFile(
|
|
313
|
+
return this.readFile(join3(this.skillsDir, `${id}.md`));
|
|
144
314
|
}
|
|
145
315
|
// ── Write ───────────────────────────────────────────────────────────────
|
|
146
316
|
savePending(lesson) {
|
|
@@ -151,42 +321,42 @@ var FileSkillStore = class {
|
|
|
151
321
|
}
|
|
152
322
|
const id = this.generateId(lesson.name);
|
|
153
323
|
const file = { ...lesson, id, approved_at: void 0 };
|
|
154
|
-
this.writeFile(
|
|
324
|
+
this.writeFile(join3(this.pendingDir, `${id}.md`), file);
|
|
155
325
|
return file;
|
|
156
326
|
}
|
|
157
327
|
approve(id) {
|
|
158
328
|
this.validateId(id);
|
|
159
|
-
const src =
|
|
160
|
-
if (!
|
|
329
|
+
const src = join3(this.pendingDir, `${id}.md`);
|
|
330
|
+
if (!existsSync3(src)) return false;
|
|
161
331
|
const skill = this.readFile(src);
|
|
162
332
|
if (!skill) return false;
|
|
163
333
|
skill.approved_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
164
|
-
const dest =
|
|
334
|
+
const dest = join3(this.skillsDir, `${id}.md`);
|
|
165
335
|
this.writeFile(dest, skill);
|
|
166
336
|
unlinkSync(src);
|
|
167
337
|
return true;
|
|
168
338
|
}
|
|
169
339
|
reject(id) {
|
|
170
340
|
this.validateId(id);
|
|
171
|
-
const src =
|
|
172
|
-
if (!
|
|
173
|
-
const dest =
|
|
341
|
+
const src = join3(this.pendingDir, `${id}.md`);
|
|
342
|
+
if (!existsSync3(src)) return false;
|
|
343
|
+
const dest = join3(this.rejectedDir, `${id}.md`);
|
|
174
344
|
renameSync(src, dest);
|
|
175
345
|
return true;
|
|
176
346
|
}
|
|
177
347
|
disable(id) {
|
|
178
348
|
this.validateId(id);
|
|
179
|
-
const src =
|
|
180
|
-
if (!
|
|
181
|
-
const dest =
|
|
349
|
+
const src = join3(this.skillsDir, `${id}.md`);
|
|
350
|
+
if (!existsSync3(src)) return false;
|
|
351
|
+
const dest = join3(this.rejectedDir, `${id}.md`);
|
|
182
352
|
renameSync(src, dest);
|
|
183
353
|
return true;
|
|
184
354
|
}
|
|
185
355
|
remove(id) {
|
|
186
356
|
this.validateId(id);
|
|
187
357
|
for (const dir of [this.skillsDir, this.pendingDir, this.rejectedDir]) {
|
|
188
|
-
const path =
|
|
189
|
-
if (
|
|
358
|
+
const path = join3(dir, `${id}.md`);
|
|
359
|
+
if (existsSync3(path)) {
|
|
190
360
|
unlinkSync(path);
|
|
191
361
|
return true;
|
|
192
362
|
}
|
|
@@ -205,19 +375,19 @@ var FileSkillStore = class {
|
|
|
205
375
|
}
|
|
206
376
|
}
|
|
207
377
|
readDir(dir) {
|
|
208
|
-
if (!
|
|
378
|
+
if (!existsSync3(dir)) return [];
|
|
209
379
|
const files = readdirSync(dir).filter((f) => f.endsWith(".md"));
|
|
210
380
|
const skills = [];
|
|
211
381
|
for (const f of files) {
|
|
212
|
-
const skill = this.readFile(
|
|
382
|
+
const skill = this.readFile(join3(dir, f));
|
|
213
383
|
if (skill) skills.push(skill);
|
|
214
384
|
}
|
|
215
385
|
return skills.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
216
386
|
}
|
|
217
387
|
readFile(path) {
|
|
218
|
-
if (!
|
|
388
|
+
if (!existsSync3(path)) return null;
|
|
219
389
|
try {
|
|
220
|
-
const content =
|
|
390
|
+
const content = readFileSync3(path, "utf-8");
|
|
221
391
|
return this.parseSkillFile(content, basename(path, ".md"));
|
|
222
392
|
} catch {
|
|
223
393
|
return null;
|
|
@@ -225,7 +395,7 @@ var FileSkillStore = class {
|
|
|
225
395
|
}
|
|
226
396
|
writeFile(path, skill) {
|
|
227
397
|
const content = this.formatSkillFile(skill);
|
|
228
|
-
|
|
398
|
+
writeFileSync3(path, content, "utf-8");
|
|
229
399
|
}
|
|
230
400
|
parseSkillFile(content, id) {
|
|
231
401
|
const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
@@ -274,8 +444,8 @@ var FileSkillStore = class {
|
|
|
274
444
|
};
|
|
275
445
|
|
|
276
446
|
// src/skills/trust.ts
|
|
277
|
-
import { readFileSync as
|
|
278
|
-
import { join as
|
|
447
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
|
|
448
|
+
import { join as join4, dirname } from "path";
|
|
279
449
|
var DEFAULT_TRUST = {
|
|
280
450
|
trusted: [],
|
|
281
451
|
blocked: [],
|
|
@@ -292,9 +462,9 @@ var TrustManager = class {
|
|
|
292
462
|
config;
|
|
293
463
|
dailyCounts;
|
|
294
464
|
constructor(baseDir) {
|
|
295
|
-
this.trustPath =
|
|
296
|
-
this.statsPath =
|
|
297
|
-
|
|
465
|
+
this.trustPath = join4(baseDir, "trust.json");
|
|
466
|
+
this.statsPath = join4(baseDir, "state", "daily_counts.json");
|
|
467
|
+
mkdirSync4(join4(baseDir, "state"), { recursive: true });
|
|
298
468
|
this.config = this.loadTrust();
|
|
299
469
|
this.dailyCounts = this.loadDailyCounts();
|
|
300
470
|
}
|
|
@@ -337,9 +507,9 @@ var TrustManager = class {
|
|
|
337
507
|
}
|
|
338
508
|
// ── Private ─────────────────────────────────────────────────────────────
|
|
339
509
|
loadTrust() {
|
|
340
|
-
if (!
|
|
510
|
+
if (!existsSync4(this.trustPath)) return { ...DEFAULT_TRUST, trusted: [], blocked: [] };
|
|
341
511
|
try {
|
|
342
|
-
const raw = JSON.parse(
|
|
512
|
+
const raw = JSON.parse(readFileSync4(this.trustPath, "utf-8"));
|
|
343
513
|
return {
|
|
344
514
|
trusted: Array.isArray(raw.trusted) ? raw.trusted.filter((a) => typeof a === "string") : [],
|
|
345
515
|
blocked: Array.isArray(raw.blocked) ? raw.blocked.filter((a) => typeof a === "string") : [],
|
|
@@ -350,14 +520,14 @@ var TrustManager = class {
|
|
|
350
520
|
}
|
|
351
521
|
}
|
|
352
522
|
saveTrust() {
|
|
353
|
-
|
|
354
|
-
|
|
523
|
+
mkdirSync4(dirname(this.trustPath), { recursive: true });
|
|
524
|
+
writeFileSync4(this.trustPath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
355
525
|
}
|
|
356
526
|
loadDailyCounts() {
|
|
357
527
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
358
|
-
if (!
|
|
528
|
+
if (!existsSync4(this.statsPath)) return { date: today, total: 0, perAgent: {} };
|
|
359
529
|
try {
|
|
360
|
-
const data = JSON.parse(
|
|
530
|
+
const data = JSON.parse(readFileSync4(this.statsPath, "utf-8"));
|
|
361
531
|
if (data.date !== today) return { date: today, total: 0, perAgent: {} };
|
|
362
532
|
return data;
|
|
363
533
|
} catch {
|
|
@@ -365,7 +535,7 @@ var TrustManager = class {
|
|
|
365
535
|
}
|
|
366
536
|
}
|
|
367
537
|
saveDailyCounts() {
|
|
368
|
-
|
|
538
|
+
writeFileSync4(this.statsPath, JSON.stringify(this.dailyCounts, null, 2), "utf-8");
|
|
369
539
|
}
|
|
370
540
|
refreshDailyCountsIfNewDay() {
|
|
371
541
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -1212,54 +1382,6 @@ function readBody2(req) {
|
|
|
1212
1382
|
});
|
|
1213
1383
|
}
|
|
1214
1384
|
|
|
1215
|
-
// src/cli/adapter/openclaw.ts
|
|
1216
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
|
|
1217
|
-
import { join as join4 } from "path";
|
|
1218
|
-
import { homedir as homedir2 } from "os";
|
|
1219
|
-
import { execSync } from "child_process";
|
|
1220
|
-
var OPENCLAW_CONFIG = join4(homedir2(), ".openclaw", "openclaw.json");
|
|
1221
|
-
var BACKUP_PATH = join4(homedir2(), ".become", "state", "original_openclaw.json");
|
|
1222
|
-
function patchOpenClaw(config) {
|
|
1223
|
-
if (!existsSync4(OPENCLAW_CONFIG)) {
|
|
1224
|
-
throw new Error(`OpenClaw config not found at ${OPENCLAW_CONFIG}`);
|
|
1225
|
-
}
|
|
1226
|
-
const raw = readFileSync4(OPENCLAW_CONFIG, "utf-8");
|
|
1227
|
-
const clawConfig = JSON.parse(raw);
|
|
1228
|
-
mkdirSync4(join4(homedir2(), ".become", "state"), { recursive: true });
|
|
1229
|
-
writeFileSync4(BACKUP_PATH, raw, "utf-8");
|
|
1230
|
-
if (!clawConfig.models) clawConfig.models = {};
|
|
1231
|
-
if (!clawConfig.models.providers) clawConfig.models.providers = {};
|
|
1232
|
-
clawConfig.models.providers.become = {
|
|
1233
|
-
api: "anthropic-messages",
|
|
1234
|
-
baseUrl: `http://127.0.0.1:${config.proxy_port}`,
|
|
1235
|
-
apiKey: config.llm_api_key
|
|
1236
|
-
};
|
|
1237
|
-
if (clawConfig.agents?.defaults?.model?.primary) {
|
|
1238
|
-
const original = clawConfig.agents.defaults.model.primary;
|
|
1239
|
-
clawConfig.models.providers.become._originalModel = original;
|
|
1240
|
-
const modelId = original.includes("/") ? original.split("/").slice(1).join("/") : original;
|
|
1241
|
-
clawConfig.agents.defaults.model.primary = `become/${modelId}`;
|
|
1242
|
-
}
|
|
1243
|
-
writeFileSync4(OPENCLAW_CONFIG, JSON.stringify(clawConfig, null, 2), "utf-8");
|
|
1244
|
-
try {
|
|
1245
|
-
execSync("openclaw gateway restart", { stdio: "pipe", timeout: 15e3 });
|
|
1246
|
-
} catch {
|
|
1247
|
-
console.log("Warning: Could not restart OpenClaw gateway. Restart it manually: openclaw gateway restart");
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
function restoreOpenClaw() {
|
|
1251
|
-
if (!existsSync4(BACKUP_PATH)) {
|
|
1252
|
-
throw new Error("No backup found. Was become ever turned on?");
|
|
1253
|
-
}
|
|
1254
|
-
const backup = readFileSync4(BACKUP_PATH, "utf-8");
|
|
1255
|
-
writeFileSync4(OPENCLAW_CONFIG, backup, "utf-8");
|
|
1256
|
-
try {
|
|
1257
|
-
execSync("openclaw gateway restart", { stdio: "pipe", timeout: 15e3 });
|
|
1258
|
-
} catch {
|
|
1259
|
-
console.log("Warning: Could not restart OpenClaw gateway. Restart it manually: openclaw gateway restart");
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
1385
|
// src/cli/adapter/ironclaw.ts
|
|
1264
1386
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync5, mkdirSync as mkdirSync5, copyFileSync } from "fs";
|
|
1265
1387
|
import { join as join5 } from "path";
|
|
@@ -1443,7 +1565,7 @@ Patching ${config.agent_type} config...`);
|
|
|
1443
1565
|
console.log(` baseUrl: ${config.llm_base_url} \u2192 localhost:${config.proxy_port}`);
|
|
1444
1566
|
switch (config.agent_type) {
|
|
1445
1567
|
case "openclaw":
|
|
1446
|
-
patchOpenClaw(config);
|
|
1568
|
+
patchOpenClaw(config, config.openclaw_agent_id);
|
|
1447
1569
|
break;
|
|
1448
1570
|
case "ironclaw":
|
|
1449
1571
|
patchIronClaw(config);
|