@better_openclaw/betterclaw 2.1.2 → 2.2.1
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 +1 -1
- package/src/index.ts +60 -1
- package/src/learner.ts +1 -1
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -87,6 +87,7 @@ export default {
|
|
|
87
87
|
|
|
88
88
|
// Track whether async init has completed
|
|
89
89
|
let initialized = false;
|
|
90
|
+
let learnerRunning = false;
|
|
90
91
|
const initPromise = (async () => {
|
|
91
92
|
try {
|
|
92
93
|
await ctxManager.load();
|
|
@@ -231,6 +232,16 @@ export default {
|
|
|
231
232
|
}
|
|
232
233
|
: null;
|
|
233
234
|
|
|
235
|
+
const triggerIds = ["low-battery-away", "unusual-inactivity", "sleep-deficit", "routine-deviation", "health-weekly-digest"];
|
|
236
|
+
const cooldowns: Record<string, number> = {};
|
|
237
|
+
if (patterns?.triggerCooldowns) {
|
|
238
|
+
for (const id of triggerIds) {
|
|
239
|
+
const ts = patterns.triggerCooldowns[id];
|
|
240
|
+
if (ts != null) cooldowns[id] = ts;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const triggers = patterns ? { cooldowns } : null;
|
|
244
|
+
|
|
234
245
|
respond(true, {
|
|
235
246
|
tier: runtime.tier,
|
|
236
247
|
smartMode: runtime.smartMode,
|
|
@@ -240,7 +251,8 @@ export default {
|
|
|
240
251
|
meta,
|
|
241
252
|
routines,
|
|
242
253
|
timestamps,
|
|
243
|
-
triageProfile: profile
|
|
254
|
+
triageProfile: profile ?? null,
|
|
255
|
+
triggers,
|
|
244
256
|
});
|
|
245
257
|
} catch (err) {
|
|
246
258
|
api.logger.error(`betterclaw.context error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -248,6 +260,53 @@ export default {
|
|
|
248
260
|
}
|
|
249
261
|
});
|
|
250
262
|
|
|
263
|
+
// Learn RPC — trigger on-demand triage profile learning
|
|
264
|
+
api.registerGatewayMethod("betterclaw.learn", async ({ respond }) => {
|
|
265
|
+
try {
|
|
266
|
+
if (!initialized) await initPromise;
|
|
267
|
+
|
|
268
|
+
if (learnerRunning) {
|
|
269
|
+
respond(true, { ok: false, error: "already-running" });
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Soft cooldown: 1 hour since last profile
|
|
274
|
+
const profile = await loadTriageProfile(stateDir);
|
|
275
|
+
if (profile?.computedAt) {
|
|
276
|
+
const elapsed = Date.now() / 1000 - profile.computedAt;
|
|
277
|
+
if (elapsed < 3600) {
|
|
278
|
+
const nextAvailableAt = profile.computedAt + 3600;
|
|
279
|
+
respond(true, { ok: false, error: "cooldown", nextAvailableAt });
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
learnerRunning = true;
|
|
285
|
+
try {
|
|
286
|
+
await runLearner({
|
|
287
|
+
stateDir,
|
|
288
|
+
workspaceDir: path.join(os.homedir(), ".openclaw", "workspace"),
|
|
289
|
+
context: ctxManager,
|
|
290
|
+
events: eventLog,
|
|
291
|
+
reactions: reactionTracker,
|
|
292
|
+
api,
|
|
293
|
+
});
|
|
294
|
+
const updatedProfile = await loadTriageProfile(stateDir);
|
|
295
|
+
respond(true, {
|
|
296
|
+
ok: true,
|
|
297
|
+
summary: updatedProfile?.summary ?? null,
|
|
298
|
+
computedAt: updatedProfile?.computedAt ?? null,
|
|
299
|
+
});
|
|
300
|
+
} finally {
|
|
301
|
+
learnerRunning = false;
|
|
302
|
+
}
|
|
303
|
+
} catch (err) {
|
|
304
|
+
learnerRunning = false;
|
|
305
|
+
api.logger.error(`betterclaw.learn error: ${err instanceof Error ? err.message : String(err)}`);
|
|
306
|
+
respond(true, { ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
251
310
|
// Snapshot RPC — bulk-apply device state for Smart Mode catch-up
|
|
252
311
|
api.registerGatewayMethod("betterclaw.snapshot", async ({ params, respond }) => {
|
|
253
312
|
try {
|
package/src/learner.ts
CHANGED
|
@@ -172,7 +172,7 @@ export async function runLearner(deps: RunLearnerDeps): Promise<void> {
|
|
|
172
172
|
await api.runtime.subagent.waitForRun({ runId, timeoutMs: 60000 });
|
|
173
173
|
|
|
174
174
|
// 10. Read response
|
|
175
|
-
const messages = await api.runtime.subagent.getSessionMessages({
|
|
175
|
+
const { messages } = await api.runtime.subagent.getSessionMessages({
|
|
176
176
|
sessionKey: "betterclaw-learn",
|
|
177
177
|
limit: 5,
|
|
178
178
|
});
|