@openclawbrain/cli 0.4.21 → 0.4.22
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/dist/src/cli.js +20 -2
- package/dist/src/local-learner.js +9 -7
- package/dist/src/session-store.js +33 -2
- package/dist/src/session-tail.js +36 -1
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -33,6 +33,11 @@ const OPENCLAWBRAIN_EMBEDDER_MODEL_ENV = "OPENCLAWBRAIN_EMBEDDER_MODEL";
|
|
|
33
33
|
const OPENCLAWBRAIN_INSTALL_SKIP_EMBEDDER_PROVISION_ENV = "OPENCLAWBRAIN_INSTALL_SKIP_EMBEDDER_PROVISION";
|
|
34
34
|
const LEGACY_COMPAT_PACKAGE_NAME = "@jonathangu/openclawbrain";
|
|
35
35
|
const INSTALL_COMPATIBLE_LOCAL_TEACHER_MODEL_PREFIXES = [
|
|
36
|
+
"unsloth-qwen3.5-27b:q4_k_m",
|
|
37
|
+
"unsloth-qwen3.5-27b",
|
|
38
|
+
"qwen3.5:32b",
|
|
39
|
+
"qwen3.5:27b",
|
|
40
|
+
"qwen3.5:14b",
|
|
36
41
|
"qwen3.5:9b",
|
|
37
42
|
"qwen3.5:8b",
|
|
38
43
|
"qwen3:8b",
|
|
@@ -5111,7 +5116,13 @@ function listWatchRuntimeEventExportBundleRoots(scanRoot) {
|
|
|
5111
5116
|
.map((entry) => path.join(scanRoot, entry.name))
|
|
5112
5117
|
.sort((left, right) => left.localeCompare(right));
|
|
5113
5118
|
}
|
|
5114
|
-
async function replayWatchScanRootIntoTeacherLoop(teacherLoop, scanRoot) {
|
|
5119
|
+
async function replayWatchScanRootIntoTeacherLoop(teacherLoop, scanRoot, options = {}) {
|
|
5120
|
+
if (options.skip === true) {
|
|
5121
|
+
return {
|
|
5122
|
+
replayedBundleCount: 0,
|
|
5123
|
+
replayedEventCount: 0
|
|
5124
|
+
};
|
|
5125
|
+
}
|
|
5115
5126
|
const seenExportDigests = new Set();
|
|
5116
5127
|
const bundles = listWatchRuntimeEventExportBundleRoots(scanRoot)
|
|
5117
5128
|
.map((rootDir) => {
|
|
@@ -5733,6 +5744,7 @@ export async function createWatchCommandRuntime(input) {
|
|
|
5733
5744
|
const restoredSeenExportCount = restoredTeacherState.snapshot.state?.seenExportDigests.length ?? 0;
|
|
5734
5745
|
log(`Restored teacher snapshot: seen=${restoredSeenExportCount} artifacts=${restoredTeacherState.snapshot.teacher.artifactCount}`);
|
|
5735
5746
|
}
|
|
5747
|
+
const restoredSeenExportCount = restoredTeacherState.snapshot?.state?.seenExportDigests.length ?? 0;
|
|
5736
5748
|
const resolvedWatchProfileScope = input.profileRoots === undefined
|
|
5737
5749
|
? resolveWatchProfileRootsForActivationRoot(activationRoot)
|
|
5738
5750
|
: {
|
|
@@ -5774,7 +5786,13 @@ export async function createWatchCommandRuntime(input) {
|
|
|
5774
5786
|
replayedEventCount: 0
|
|
5775
5787
|
};
|
|
5776
5788
|
try {
|
|
5777
|
-
|
|
5789
|
+
const skipStoredReplay = restoredSeenExportCount > 0 && startupWarnings.length === 0;
|
|
5790
|
+
if (skipStoredReplay) {
|
|
5791
|
+
log(`Stored replay skipped: restored teacher snapshot already tracks ${restoredSeenExportCount} export digest${restoredSeenExportCount === 1 ? "" : "s"}.`);
|
|
5792
|
+
}
|
|
5793
|
+
replayState = await replayWatchScanRootIntoTeacherLoop(teacherLoop, scanRoot, {
|
|
5794
|
+
skip: skipStoredReplay
|
|
5795
|
+
});
|
|
5778
5796
|
}
|
|
5779
5797
|
catch (error) {
|
|
5780
5798
|
const message = formatWatchError(error);
|
|
@@ -928,13 +928,15 @@ export function advanceAlwaysOnLearningRuntime(input) {
|
|
|
928
928
|
const schedule = selectScheduledSlices(pending, current.learnedEventExport, cadence);
|
|
929
929
|
const selectedSlices = schedule.selected;
|
|
930
930
|
const learnedEventExport = mergeNormalizedEventExports(current.learnedEventExport, selectedSlices);
|
|
931
|
-
const runtimeGraphSnapshot =
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
...
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
931
|
+
const runtimeGraphSnapshot = selectedSlices.length === 0
|
|
932
|
+
? null
|
|
933
|
+
: buildRuntimeGraphSnapshot({
|
|
934
|
+
...input,
|
|
935
|
+
state: {
|
|
936
|
+
...current,
|
|
937
|
+
structuralController
|
|
938
|
+
}
|
|
939
|
+
});
|
|
938
940
|
const runtimeGraph = runtimeGraphSnapshot?.graph ?? current.runtimeGraph;
|
|
939
941
|
const runtimePlasticity = runtimeGraphSnapshot?.plasticity ?? current.runtimePlasticity;
|
|
940
942
|
const sparseFeedbackObservedAt = input.builtAt ?? learnedEventExport?.range.lastCreatedAt ?? learnedEventExport?.range.firstCreatedAt ?? current.lastMaterializedAt ?? "1970-01-01T00:00:00.000Z";
|
|
@@ -171,6 +171,35 @@ function parseOpenClawSessionRecord(value, lineNumber) {
|
|
|
171
171
|
timestamp: expectString(record.timestamp, `${lineNumber}.timestamp`)
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
+
case "compaction": {
|
|
175
|
+
const data = {};
|
|
176
|
+
if (record.summary !== undefined) {
|
|
177
|
+
data.summary = expectString(record.summary, `${lineNumber}.summary`);
|
|
178
|
+
}
|
|
179
|
+
if (record.firstKeptEntryId !== undefined) {
|
|
180
|
+
data.firstKeptEntryId = expectString(record.firstKeptEntryId, `${lineNumber}.firstKeptEntryId`);
|
|
181
|
+
}
|
|
182
|
+
if (record.tokensBefore !== undefined) {
|
|
183
|
+
data.tokensBefore = expectNumber(record.tokensBefore, `${lineNumber}.tokensBefore`);
|
|
184
|
+
}
|
|
185
|
+
if (record.details !== undefined) {
|
|
186
|
+
data.details = expectRecord(record.details, `${lineNumber}.details`);
|
|
187
|
+
}
|
|
188
|
+
if (record.fromHook !== undefined) {
|
|
189
|
+
if (typeof record.fromHook !== "boolean") {
|
|
190
|
+
throw new Error(`${lineNumber}.fromHook must be a boolean`);
|
|
191
|
+
}
|
|
192
|
+
data.fromHook = record.fromHook;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
type: "custom",
|
|
196
|
+
customType: "openclaw.compaction",
|
|
197
|
+
data,
|
|
198
|
+
id: expectString(record.id, `${lineNumber}.id`),
|
|
199
|
+
parentId: expectNullableString(record.parentId, `${lineNumber}.parentId`),
|
|
200
|
+
timestamp: expectString(record.timestamp, `${lineNumber}.timestamp`)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
174
203
|
case "message":
|
|
175
204
|
return {
|
|
176
205
|
type,
|
|
@@ -185,7 +214,9 @@ function parseOpenClawSessionRecord(value, lineNumber) {
|
|
|
185
214
|
}
|
|
186
215
|
function parseMessagePayload(value, path) {
|
|
187
216
|
const payload = expectRecord(value, path);
|
|
188
|
-
const content =
|
|
217
|
+
const content = typeof payload.content === "string"
|
|
218
|
+
? [{ type: "text", text: payload.content }]
|
|
219
|
+
: expectArray(payload.content, `${path}.content`).map((entry, index) => parseContentPart(entry, `${path}.content[${index}]`));
|
|
189
220
|
return {
|
|
190
221
|
...payload,
|
|
191
222
|
role: expectString(payload.role, `${path}.role`),
|
|
@@ -267,4 +298,4 @@ function expectNumber(value, path) {
|
|
|
267
298
|
}
|
|
268
299
|
return value;
|
|
269
300
|
}
|
|
270
|
-
//# sourceMappingURL=session-store.js.map
|
|
301
|
+
//# sourceMappingURL=session-store.js.map
|
package/dist/src/session-tail.js
CHANGED
|
@@ -383,6 +383,7 @@ export class OpenClawLocalSessionTail {
|
|
|
383
383
|
const firstPoll = this.initialized === false;
|
|
384
384
|
const warnings = [];
|
|
385
385
|
const changes = [];
|
|
386
|
+
const observedKeys = new Set();
|
|
386
387
|
const sources = discoverOpenClawSessionStores({
|
|
387
388
|
...(this.homeDir === undefined ? {} : { homeDir: this.homeDir }),
|
|
388
389
|
...(this.profileRoots === undefined ? {} : { profileRoots: this.profileRoots })
|
|
@@ -409,9 +410,21 @@ export class OpenClawLocalSessionTail {
|
|
|
409
410
|
continue;
|
|
410
411
|
}
|
|
411
412
|
const key = cursorKey(source.indexPath, sessionKey);
|
|
413
|
+
observedKeys.add(key);
|
|
412
414
|
const existing = this.cursorBySession.get(key) ?? null;
|
|
413
415
|
const sessionFile = typeof entry.sessionFile === "string" && entry.sessionFile.trim().length > 0 ? path.resolve(entry.sessionFile) : null;
|
|
414
416
|
if (sessionFile === null) {
|
|
417
|
+
const nextCursor = createCursor(source.indexPath, sessionKey, entry.sessionId, null, entry.updatedAt, 0, 0);
|
|
418
|
+
this.cursorBySession.set(key, nextCursor);
|
|
419
|
+
const changed = existing === null ||
|
|
420
|
+
existing.sessionId !== entry.sessionId ||
|
|
421
|
+
existing.sessionFile !== null ||
|
|
422
|
+
existing.updatedAt !== entry.updatedAt ||
|
|
423
|
+
existing.rawRecordCount !== 0 ||
|
|
424
|
+
existing.bridgedEventCount !== 0;
|
|
425
|
+
if (!changed) {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
415
428
|
changes.push(createChange({
|
|
416
429
|
source,
|
|
417
430
|
sessionKey,
|
|
@@ -425,6 +438,17 @@ export class OpenClawLocalSessionTail {
|
|
|
425
438
|
continue;
|
|
426
439
|
}
|
|
427
440
|
if (!existsSync(sessionFile)) {
|
|
441
|
+
const nextCursor = createCursor(source.indexPath, sessionKey, entry.sessionId, sessionFile, entry.updatedAt, 0, 0);
|
|
442
|
+
this.cursorBySession.set(key, nextCursor);
|
|
443
|
+
const changed = existing === null ||
|
|
444
|
+
existing.sessionId !== entry.sessionId ||
|
|
445
|
+
existing.sessionFile !== sessionFile ||
|
|
446
|
+
existing.updatedAt !== entry.updatedAt ||
|
|
447
|
+
existing.rawRecordCount !== 0 ||
|
|
448
|
+
existing.bridgedEventCount !== 0;
|
|
449
|
+
if (!changed) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
428
452
|
changes.push(createChange({
|
|
429
453
|
source,
|
|
430
454
|
sessionKey,
|
|
@@ -535,6 +559,17 @@ export class OpenClawLocalSessionTail {
|
|
|
535
559
|
}));
|
|
536
560
|
}
|
|
537
561
|
}
|
|
562
|
+
let prunedCursorCount = 0;
|
|
563
|
+
for (const key of [...this.cursorBySession.keys()]) {
|
|
564
|
+
if (observedKeys.has(key)) {
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
this.cursorBySession.delete(key);
|
|
568
|
+
prunedCursorCount += 1;
|
|
569
|
+
}
|
|
570
|
+
if (prunedCursorCount > 0) {
|
|
571
|
+
warnings.push(`session tail pruned ${prunedCursorCount} stale cursor entr${prunedCursorCount === 1 ? "y" : "ies"}`);
|
|
572
|
+
}
|
|
538
573
|
this.initialized = true;
|
|
539
574
|
const noopReason = firstPoll && !changes.some((change) => change.scannedEventExport !== null)
|
|
540
575
|
? "seeded_existing_sessions"
|
|
@@ -599,4 +634,4 @@ export class OpenClawLocalSessionTail {
|
|
|
599
634
|
export function createOpenClawLocalSessionTail(input = {}) {
|
|
600
635
|
return new OpenClawLocalSessionTail(input);
|
|
601
636
|
}
|
|
602
|
-
//# sourceMappingURL=session-tail.js.map
|
|
637
|
+
//# sourceMappingURL=session-tail.js.map
|
package/package.json
CHANGED