@openclawbrain/cli 0.4.25 → 0.4.26
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 +5 -5
- package/dist/src/index.js +8 -2
- package/dist/src/traced-learning-bridge.js +165 -2
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -17,7 +17,7 @@ import { inspectOpenClawBrainHookStatus, inspectOpenClawBrainPluginAllowlist } f
|
|
|
17
17
|
import { describeOpenClawBrainInstallIdentity, describeOpenClawBrainInstallLayout, findInstalledOpenClawBrainPlugin, getOpenClawBrainKnownPluginIds, normalizeOpenClawBrainPluginsConfig, pinInstalledOpenClawBrainPluginActivationRoot, resolveOpenClawBrainInstallTarget } from "./openclaw-plugin-install.js";
|
|
18
18
|
import { buildOpenClawBrainConvergeRestartPlan, classifyOpenClawBrainConvergeVerification, describeOpenClawBrainConvergeChangeReasons, diffOpenClawBrainConvergeRuntimeFingerprint, finalizeOpenClawBrainConvergeResult, planOpenClawBrainConvergePluginAction, shouldReplaceOpenClawBrainInstallBeforeConverge } from "./install-converge.js";
|
|
19
19
|
import { loadAttachmentPolicyDeclaration, resolveEffectiveAttachmentPolicyTruth, writeAttachmentPolicyDeclaration } from "./attachment-policy-truth.js";
|
|
20
|
-
import { DEFAULT_WATCH_POLL_INTERVAL_SECONDS, buildNormalizedEventExportFromScannedEvents, bootstrapRuntimeAttach,
|
|
20
|
+
import { DEFAULT_WATCH_POLL_INTERVAL_SECONDS, buildNormalizedEventExportFromScannedEvents, bootstrapRuntimeAttach, clearOpenClawProfileRuntimeLoadProof, compileRuntimeContext, createAsyncTeacherLiveLoop, createOpenClawLocalSessionTail, createRuntimeEventExportScanner, describeCurrentProfileBrainStatusWithReport, formatOperatorRollbackReport, listOpenClawProfileRuntimeLoadProofs, loadRuntimeEventExportBundle, loadWatchTeacherSnapshotState, persistWatchTeacherSnapshot, rollbackRuntimeAttach, resolveAttachmentRuntimeLoadProofsPath, resolveOperatorTeacherSnapshotPath, resolveAsyncTeacherLiveLoopSnapshotPath, resolveWatchSessionTailCursorPath, resolveWatchStateRoot, resolveWatchTeacherSnapshotPath, scanLiveEventExport, scanRecordedSession, summarizeLearningPathFromMaterialization, summarizeNormalizedEventExportLabelFlow, summarizeTeacherNoArtifactCycle, writeScannedEventExportBundle } from "./index.js";
|
|
21
21
|
import { appendLearningUpdateLogs } from "./learning-spine.js";
|
|
22
22
|
import { buildPassiveLearningSessionExportFromOpenClawSessionStore } from "./local-session-passive-learning.js";
|
|
23
23
|
import { reindexMaterializationCandidateWithEmbedder } from "./materialization-embedder.js";
|
|
@@ -1692,8 +1692,7 @@ function inspectInstallConvergeVerification(parsed) {
|
|
|
1692
1692
|
openclawHome: parsed.openclawHome,
|
|
1693
1693
|
...(targetInspection.profileId === null ? {} : { profileId: targetInspection.profileId })
|
|
1694
1694
|
};
|
|
1695
|
-
const status =
|
|
1696
|
-
const report = buildOperatorSurfaceReport(operatorInput);
|
|
1695
|
+
const { status, report } = describeCurrentProfileBrainStatusWithReport(operatorInput);
|
|
1697
1696
|
const normalizedStatusAndReport = applyAttachmentPolicyTruth(status, report);
|
|
1698
1697
|
const installHook = summarizeStatusInstallHook(parsed.openclawHome);
|
|
1699
1698
|
const attachmentTruth = summarizeStatusAttachmentTruth({
|
|
@@ -6364,9 +6363,10 @@ export function runOperatorCli(argv = process.argv.slice(2)) {
|
|
|
6364
6363
|
: { profileId: targetInspection.profileId }),
|
|
6365
6364
|
teacherSnapshotPath: resolveOperatorTeacherSnapshotPath(activationRoot, statusOrRollback.input.teacherSnapshotPath)
|
|
6366
6365
|
};
|
|
6367
|
-
const
|
|
6366
|
+
const statusWithReport = describeCurrentProfileBrainStatusWithReport(operatorInput);
|
|
6367
|
+
const status = statusWithReport.status;
|
|
6368
6368
|
const tracedLearning = buildTracedLearningStatusSurface(activationRoot);
|
|
6369
|
-
const normalizedStatusAndReport = applyAttachmentPolicyTruth(status, statusOrRollback.json ? null :
|
|
6369
|
+
const normalizedStatusAndReport = applyAttachmentPolicyTruth(status, statusOrRollback.json ? null : statusWithReport.report);
|
|
6370
6370
|
if (statusOrRollback.json) {
|
|
6371
6371
|
console.log(JSON.stringify({
|
|
6372
6372
|
...normalizedStatusAndReport.status,
|
package/dist/src/index.js
CHANGED
|
@@ -8031,9 +8031,15 @@ export function buildOperatorSurfaceReport(input) {
|
|
|
8031
8031
|
findings
|
|
8032
8032
|
};
|
|
8033
8033
|
}
|
|
8034
|
-
export function
|
|
8034
|
+
export function describeCurrentProfileBrainStatusWithReport(input) {
|
|
8035
8035
|
const report = buildOperatorSurfaceReport(input);
|
|
8036
|
-
return
|
|
8036
|
+
return {
|
|
8037
|
+
report,
|
|
8038
|
+
status: buildCurrentProfileBrainStatusFromReport(report, report.manyProfile.declaredAttachmentPolicy, normalizeOptionalString(input.profileId) ?? null)
|
|
8039
|
+
};
|
|
8040
|
+
}
|
|
8041
|
+
export function describeCurrentProfileBrainStatus(input) {
|
|
8042
|
+
return describeCurrentProfileBrainStatusWithReport(input).status;
|
|
8037
8043
|
}
|
|
8038
8044
|
export function formatOperatorRollbackReport(result) {
|
|
8039
8045
|
const header = result.allowed ? (result.dryRun ? "ROLLBACK ready" : "ROLLBACK ok") : "ROLLBACK blocked";
|
|
@@ -258,6 +258,169 @@ function buildDerivedAttributionCoverage(db) {
|
|
|
258
258
|
: `completed_without_evaluation=${completedWithoutEvaluationCount}; ready=${readyCount}, delayed=${delayedCount}, budget_deferred=${budgetDeferredCount}`
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
|
+
function loadJsonFile(pathname) {
|
|
262
|
+
if (!existsSync(pathname)) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
return JSON.parse(readFileSync(pathname, "utf8"));
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function resolveActivePackPaths(activationRoot) {
|
|
273
|
+
const pointers = toRecord(loadJsonFile(path.join(path.resolve(activationRoot), "activation-pointers.json")));
|
|
274
|
+
const active = toRecord(pointers?.active);
|
|
275
|
+
const packRootDir = normalizeOptionalString(active?.packRootDir)
|
|
276
|
+
?? (normalizeOptionalString(active?.packId) === null
|
|
277
|
+
? null
|
|
278
|
+
: path.join(path.resolve(activationRoot), "packs", String(active.packId)));
|
|
279
|
+
const manifestPath = normalizeOptionalString(active?.manifestPath)
|
|
280
|
+
?? (packRootDir === null ? null : path.join(packRootDir, "manifest.json"));
|
|
281
|
+
return {
|
|
282
|
+
packRootDir,
|
|
283
|
+
manifestPath
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function buildActivePackFeedbackSummary(activationRoot) {
|
|
287
|
+
const active = resolveActivePackPaths(activationRoot);
|
|
288
|
+
if (active.packRootDir === null || active.manifestPath === null) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
const manifest = toRecord(loadJsonFile(active.manifestPath));
|
|
292
|
+
const runtimeAssets = toRecord(manifest?.runtimeAssets);
|
|
293
|
+
const router = toRecord(runtimeAssets?.router);
|
|
294
|
+
const routerArtifactPath = normalizeOptionalString(router?.artifactPath);
|
|
295
|
+
if (routerArtifactPath === null) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
const routerPath = path.isAbsolute(routerArtifactPath)
|
|
299
|
+
? routerArtifactPath
|
|
300
|
+
: path.join(active.packRootDir, routerArtifactPath);
|
|
301
|
+
const routerArtifact = toRecord(loadJsonFile(routerPath));
|
|
302
|
+
const traces = Array.isArray(routerArtifact?.traces) ? routerArtifact.traces : [];
|
|
303
|
+
const verdictCounts = {
|
|
304
|
+
helpfulCount: 0,
|
|
305
|
+
irrelevantCount: 0,
|
|
306
|
+
harmfulCount: 0
|
|
307
|
+
};
|
|
308
|
+
for (const trace of traces) {
|
|
309
|
+
const traceRecord = toRecord(trace);
|
|
310
|
+
if (normalizeOptionalString(traceRecord?.supervisionKind) === "route_trace") {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const verdict = classifyContextFeedbackVerdict(Number(traceRecord?.reward ?? 0));
|
|
314
|
+
if (verdict === "helpful") {
|
|
315
|
+
verdictCounts.helpfulCount += 1;
|
|
316
|
+
}
|
|
317
|
+
else if (verdict === "harmful") {
|
|
318
|
+
verdictCounts.harmfulCount += 1;
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
verdictCounts.irrelevantCount += 1;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const routeTraceCount = normalizeCount(routerArtifact?.training?.routeTraceCount) || traces.length;
|
|
325
|
+
const supervisedTraceCount = verdictCounts.helpfulCount + verdictCounts.irrelevantCount + verdictCounts.harmfulCount;
|
|
326
|
+
if (routeTraceCount === 0 && supervisedTraceCount === 0) {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
visible: true,
|
|
331
|
+
...verdictCounts,
|
|
332
|
+
supervisedTraceCount,
|
|
333
|
+
routeTraceCount,
|
|
334
|
+
latestAgentIdentity: null,
|
|
335
|
+
latestLabel: null,
|
|
336
|
+
detail: routeTraceCount === 0
|
|
337
|
+
? "no active-pack traced routes are visible"
|
|
338
|
+
: `${verdictCounts.helpfulCount} helpful, ${verdictCounts.irrelevantCount} irrelevant, ${verdictCounts.harmfulCount} harmful; ${supervisedTraceCount}/${routeTraceCount} active-pack traced routes are supervised`
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function readIntegerNote(notes, prefix) {
|
|
342
|
+
if (!Array.isArray(notes)) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
const entry = notes.find((candidate) => typeof candidate === "string" && candidate.startsWith(prefix));
|
|
346
|
+
if (typeof entry !== "string") {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const parsed = Number.parseInt(entry.slice(prefix.length), 10);
|
|
350
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
351
|
+
}
|
|
352
|
+
function buildWatchSnapshotAttributionCoverage(activationRoot) {
|
|
353
|
+
const snapshot = toRecord(loadJsonFile(path.join(path.resolve(activationRoot), "watch", "teacher-snapshot.json")));
|
|
354
|
+
const notes = Array.isArray(snapshot?.notes)
|
|
355
|
+
? snapshot.notes
|
|
356
|
+
: Array.isArray(snapshot?.snapshot?.diagnostics?.notes)
|
|
357
|
+
? snapshot.snapshot.diagnostics.notes
|
|
358
|
+
: Array.isArray(snapshot?.diagnostics?.notes)
|
|
359
|
+
? snapshot.diagnostics.notes
|
|
360
|
+
: [];
|
|
361
|
+
const readyCount = readIntegerNote(notes, "teacher_feedback_eligible=");
|
|
362
|
+
const delayedCount = readIntegerNote(notes, "teacher_feedback_delayed=");
|
|
363
|
+
const budgetDeferredCount = readIntegerNote(notes, "teacher_feedback_budgeted_out=");
|
|
364
|
+
const budgetPerTick = readIntegerNote(notes, "teacher_budget=");
|
|
365
|
+
const delayMs = readIntegerNote(notes, "teacher_delay_ms=");
|
|
366
|
+
if (readyCount === null && delayedCount === null && budgetDeferredCount === null && budgetPerTick === null && delayMs === null) {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
visible: true,
|
|
371
|
+
gatingVisible: budgetPerTick !== null || delayMs !== null,
|
|
372
|
+
completedWithoutEvaluationCount: 0,
|
|
373
|
+
readyCount: normalizeCount(readyCount),
|
|
374
|
+
delayedCount: normalizeCount(delayedCount),
|
|
375
|
+
budgetDeferredCount: normalizeCount(budgetDeferredCount),
|
|
376
|
+
detail: `watch sparse-feedback queue: completed_without_evaluation=0, ready=${normalizeCount(readyCount)}, delayed=${normalizeCount(delayedCount)}, budget_deferred=${normalizeCount(budgetDeferredCount)}`
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
function shouldPreferActivationFeedbackSummary(current, fallback) {
|
|
380
|
+
if (fallback === null) {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
if (current.visible !== true) {
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
return normalizeCount(current.supervisedTraceCount) === 0 && normalizeCount(fallback.supervisedTraceCount) > 0;
|
|
387
|
+
}
|
|
388
|
+
function shouldPreferWatchAttributionCoverage(current, fallback) {
|
|
389
|
+
if (fallback === null) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
if (current.visible !== true || current.gatingVisible !== true) {
|
|
393
|
+
return normalizeCount(fallback.readyCount) > 0
|
|
394
|
+
|| normalizeCount(fallback.delayedCount) > 0
|
|
395
|
+
|| normalizeCount(fallback.budgetDeferredCount) > 0;
|
|
396
|
+
}
|
|
397
|
+
const currentKnown = normalizeCount(current.completedWithoutEvaluationCount)
|
|
398
|
+
+ normalizeCount(current.readyCount)
|
|
399
|
+
+ normalizeCount(current.delayedCount)
|
|
400
|
+
+ normalizeCount(current.budgetDeferredCount);
|
|
401
|
+
const fallbackKnown = normalizeCount(fallback.completedWithoutEvaluationCount)
|
|
402
|
+
+ normalizeCount(fallback.readyCount)
|
|
403
|
+
+ normalizeCount(fallback.delayedCount)
|
|
404
|
+
+ normalizeCount(fallback.budgetDeferredCount);
|
|
405
|
+
return currentKnown === 0 && fallbackKnown > 0;
|
|
406
|
+
}
|
|
407
|
+
function enrichBridgeWithActivationTruth(activationRoot, bridge) {
|
|
408
|
+
const feedbackSummary = buildActivePackFeedbackSummary(activationRoot);
|
|
409
|
+
const attributionCoverage = buildWatchSnapshotAttributionCoverage(activationRoot);
|
|
410
|
+
if (!shouldPreferActivationFeedbackSummary(bridge.feedbackSummary, feedbackSummary)
|
|
411
|
+
&& !shouldPreferWatchAttributionCoverage(bridge.attributionCoverage, attributionCoverage)) {
|
|
412
|
+
return bridge;
|
|
413
|
+
}
|
|
414
|
+
return normalizeBridgePayload({
|
|
415
|
+
...bridge,
|
|
416
|
+
feedbackSummary: shouldPreferActivationFeedbackSummary(bridge.feedbackSummary, feedbackSummary)
|
|
417
|
+
? feedbackSummary
|
|
418
|
+
: bridge.feedbackSummary,
|
|
419
|
+
attributionCoverage: shouldPreferWatchAttributionCoverage(bridge.attributionCoverage, attributionCoverage)
|
|
420
|
+
? attributionCoverage
|
|
421
|
+
: bridge.attributionCoverage
|
|
422
|
+
});
|
|
423
|
+
}
|
|
261
424
|
function normalizeLastInterruptionSummary(value) {
|
|
262
425
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
263
426
|
return null;
|
|
@@ -995,12 +1158,12 @@ export function buildTracedLearningStatusSurface(activationRoot, options = {}) {
|
|
|
995
1158
|
const persisted = loadBrainStoreTracedLearningBridge(options);
|
|
996
1159
|
const runtime = loadTracedLearningBridge(activationRoot);
|
|
997
1160
|
if (persisted.bridge !== null) {
|
|
998
|
-
return buildStatusSurface(persisted.path, mergeCanonicalStatusBridge(persisted.bridge, runtime), {
|
|
1161
|
+
return buildStatusSurface(persisted.path, enrichBridgeWithActivationTruth(activationRoot, mergeCanonicalStatusBridge(persisted.bridge, runtime)), {
|
|
999
1162
|
runtimeState: describeBridgeRuntimeState(runtime)
|
|
1000
1163
|
});
|
|
1001
1164
|
}
|
|
1002
1165
|
if (runtime.bridge !== null) {
|
|
1003
|
-
return buildStatusSurface(runtime.path, runtime.bridge);
|
|
1166
|
+
return buildStatusSurface(runtime.path, enrichBridgeWithActivationTruth(activationRoot, runtime.bridge));
|
|
1004
1167
|
}
|
|
1005
1168
|
if (persisted.error !== null) {
|
|
1006
1169
|
return defaultSurface(persisted.path, "brain_store_unreadable", persisted.error);
|
package/package.json
CHANGED