@openclawbrain/cli 0.4.2 → 0.4.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 CHANGED
@@ -1,17 +1,17 @@
1
1
  # @openclawbrain/cli
2
2
 
3
- `@openclawbrain/cli@0.4.2` is the repo's next operator CLI package surface for OpenClawBrain. The latest published CLI remains `0.4.1` until this repo state is shipped.
3
+ `@openclawbrain/cli@0.4.3` is the published operator CLI package for OpenClawBrain.
4
4
 
5
5
  Primary public flow:
6
6
 
7
7
  ```bash
8
8
  openclaw plugins install @openclawbrain/openclaw@0.4.0
9
- npx @openclawbrain/cli@0.4.2 install --openclaw-home ~/.openclaw
9
+ npx @openclawbrain/cli@0.4.3 install --openclaw-home ~/.openclaw
10
10
  openclaw gateway restart
11
- npx @openclawbrain/cli@0.4.2 status --openclaw-home ~/.openclaw --detailed
11
+ npx @openclawbrain/cli@0.4.3 status --openclaw-home ~/.openclaw --detailed
12
12
  ```
13
13
 
14
- Patch note for `0.4.2`: the CLI now persists declared attachment policy during install/attach so later `status` reads stop underreporting shared installs as `policy=null` / `undeclared`, and the package tarball now carries the full operator module surface plus traced-learning bridge needed for the canonical brain-store status path.
14
+ Patch note for `0.4.3`: the CLI now reports active-pack numeric embeddings more truthfully across alternate vector shapes, and the repo-side serve-time decision matcher is more tolerant of event-id and timestamp drift when harvesting supervision candidates.
15
15
 
16
16
  Current caveat: some hosts still warn about a plugin id mismatch because the plugin manifest uses `openclawbrain` while the package/entry hint uses `openclaw`. The install still works; treat that warning as currently cosmetic.
17
17
 
@@ -20,10 +20,10 @@ This package carries the `openclawbrain` CLI, daemon controls, import/export hel
20
20
  ## Commands
21
21
 
22
22
  ```bash
23
- npx @openclawbrain/cli@0.4.2 install --openclaw-home ~/.openclaw
24
- npx @openclawbrain/cli@0.4.2 status --openclaw-home ~/.openclaw --detailed
25
- npx @openclawbrain/cli@0.4.2 rollback --activation-root /var/openclawbrain/activation --dry-run
26
- npx @openclawbrain/cli@0.4.2 daemon status --activation-root /var/openclawbrain/activation
23
+ npx @openclawbrain/cli@0.4.3 install --openclaw-home ~/.openclaw
24
+ npx @openclawbrain/cli@0.4.3 status --openclaw-home ~/.openclaw --detailed
25
+ npx @openclawbrain/cli@0.4.3 rollback --activation-root /var/openclawbrain/activation --dry-run
26
+ npx @openclawbrain/cli@0.4.3 daemon status --activation-root /var/openclawbrain/activation
27
27
  ```
28
28
 
29
29
  If the CLI is already on your `PATH`, `openclawbrain ...` is the same command surface. The docs lead with `npx` because that is the clean-host public-registry lane that already passed on `redogfood`.
package/dist/src/cli.js CHANGED
@@ -19,6 +19,7 @@ import { loadAttachmentPolicyDeclaration, resolveEffectiveAttachmentPolicyTruth,
19
19
  import { DEFAULT_WATCH_POLL_INTERVAL_SECONDS, buildNormalizedEventExportFromScannedEvents, bootstrapRuntimeAttach, buildOperatorSurfaceReport, clearOpenClawProfileRuntimeLoadProof, compileRuntimeContext, createAsyncTeacherLiveLoop, createOpenClawLocalSessionTail, createRuntimeEventExportScanner, describeCurrentProfileBrainStatus, formatOperatorRollbackReport, listOpenClawProfileRuntimeLoadProofs, loadRuntimeEventExportBundle, loadWatchTeacherSnapshotState, persistWatchTeacherSnapshot, rollbackRuntimeAttach, resolveAttachmentRuntimeLoadProofsPath, resolveOperatorTeacherSnapshotPath, resolveAsyncTeacherLiveLoopSnapshotPath, resolveWatchSessionTailCursorPath, resolveWatchStateRoot, resolveWatchTeacherSnapshotPath, scanLiveEventExport, scanRecordedSession, summarizeLearningPathFromMaterialization, summarizeNormalizedEventExportLabelFlow, writeScannedEventExportBundle } from "./index.js";
20
20
  import { appendLearningUpdateLogs } from "./learning-spine.js";
21
21
  import { buildPassiveLearningSessionExportFromOpenClawSessionStore } from "./local-session-passive-learning.js";
22
+ import { summarizePackVectorEmbeddingState } from "./embedding-status.js";
22
23
  import { buildTracedLearningStatusSurface, loadBrainStoreTracedLearningBridge, mergeTracedLearningBridgePayload, persistBrainStoreTracedLearningBridge, writeTracedLearningBridge } from "./traced-learning-bridge.js";
23
24
  import { discoverOpenClawSessionStores, loadOpenClawSessionIndex, readOpenClawSessionFile } from "./session-store.js";
24
25
  import { readOpenClawBrainProviderDefaults, readOpenClawBrainProviderConfig, readOpenClawBrainProviderConfigFromSources, resolveOpenClawBrainProviderDefaultsPath } from "./provider-config.js";
@@ -953,11 +954,14 @@ function summarizeStatusEmbeddings(report, providerConfig) {
953
954
  requireActivationReady: true
954
955
  });
955
956
  if (activePack !== null) {
956
- totalEntryCount = activePack.vectors.entries.length;
957
- embeddedEntryCount = activePack.vectors.entries.filter((entry) => entry.embedding !== undefined).length;
958
- models = [...new Set(activePack.vectors.entries.flatMap((entry) => (entry.embedding === undefined ? [] : [entry.embedding.model])))].sort((left, right) => left.localeCompare(right));
959
- liveState = embeddedEntryCount > 0 ? "yes" : "no";
960
- liveDetail = `active pack stores ${embeddedEntryCount}/${totalEntryCount} numeric embeddings`;
957
+ const summary = summarizePackVectorEmbeddingState(activePack.vectors);
958
+ totalEntryCount = summary.vectorEntryCount;
959
+ embeddedEntryCount = summary.numericEmbeddingEntryCount;
960
+ models = summary.embeddingModels;
961
+ liveState = embeddedEntryCount === null ? "unknown" : embeddedEntryCount > 0 ? "yes" : "no";
962
+ liveDetail = embeddedEntryCount === null || totalEntryCount === null
963
+ ? "active pack vector entries were unreadable during embedding inspection"
964
+ : `active pack stores ${embeddedEntryCount}/${totalEntryCount} numeric embeddings`;
961
965
  }
962
966
  }
963
967
  catch (error) {
@@ -4544,19 +4548,7 @@ function exportLocalSessionTailChangesToScanRoot(input) {
4544
4548
  };
4545
4549
  }
4546
4550
  function summarizeVectorEmbeddingState(vectors) {
4547
- if (vectors === null || vectors === undefined) {
4548
- return {
4549
- vectorEntryCount: null,
4550
- numericEmbeddingEntryCount: null,
4551
- embeddingModels: []
4552
- };
4553
- }
4554
- const embeddingModels = [...new Set(vectors.entries.flatMap((entry) => (entry.embedding === undefined ? [] : [entry.embedding.model])))].sort((left, right) => left.localeCompare(right));
4555
- return {
4556
- vectorEntryCount: vectors.entries.length,
4557
- numericEmbeddingEntryCount: vectors.entries.filter((entry) => entry.embedding !== undefined).length,
4558
- embeddingModels
4559
- };
4551
+ return summarizePackVectorEmbeddingState(vectors);
4560
4552
  }
4561
4553
  function buildWatchEmbedTracePoint(input) {
4562
4554
  const summary = summarizeVectorEmbeddingState(input.vectors);
@@ -0,0 +1,78 @@
1
+ function isNumericArray(value) {
2
+ return Array.isArray(value) &&
3
+ value.length > 0 &&
4
+ value.every((entry) => typeof entry === "number" && Number.isFinite(entry));
5
+ }
6
+
7
+ function isNumericTypedArray(value) {
8
+ return ArrayBuffer.isView(value) &&
9
+ !(value instanceof DataView) &&
10
+ typeof value.length === "number" &&
11
+ value.length > 0 &&
12
+ Array.from(value).every((entry) => typeof entry === "number" && Number.isFinite(entry));
13
+ }
14
+
15
+ function hasNumericValues(value) {
16
+ return isNumericArray(value) || isNumericTypedArray(value);
17
+ }
18
+
19
+ function normalizeOptionalString(value) {
20
+ if (typeof value !== "string") {
21
+ return null;
22
+ }
23
+ const trimmed = value.trim();
24
+ return trimmed.length > 0 ? trimmed : null;
25
+ }
26
+
27
+ function extractNumericEmbeddingShape(entry) {
28
+ const embedding = entry?.embedding;
29
+ const candidates = [
30
+ embedding,
31
+ embedding?.values,
32
+ embedding?.vector,
33
+ embedding?.embedding,
34
+ entry?.values,
35
+ entry?.vector,
36
+ entry?.numericEmbedding,
37
+ entry?.numericEmbeddingValues,
38
+ ];
39
+ return candidates.find((candidate) => hasNumericValues(candidate)) ?? null;
40
+ }
41
+
42
+ function extractEmbeddingModel(entry) {
43
+ const candidates = [
44
+ entry?.embedding?.model,
45
+ entry?.embeddingModel,
46
+ entry?.model,
47
+ ];
48
+ for (const candidate of candidates) {
49
+ const normalized = normalizeOptionalString(candidate);
50
+ if (normalized !== null) {
51
+ return normalized;
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+
57
+ export function summarizePackVectorEmbeddingState(vectors) {
58
+ if (!vectors || !Array.isArray(vectors.entries)) {
59
+ return {
60
+ vectorEntryCount: null,
61
+ numericEmbeddingEntryCount: null,
62
+ embeddingModels: []
63
+ };
64
+ }
65
+ const embeddingModels = [...new Set(vectors.entries
66
+ .flatMap((entry) => {
67
+ if (extractNumericEmbeddingShape(entry) === null) {
68
+ return [];
69
+ }
70
+ const model = extractEmbeddingModel(entry);
71
+ return model === null ? [] : [model];
72
+ }))].sort((left, right) => left.localeCompare(right));
73
+ return {
74
+ vectorEntryCount: vectors.entries.length,
75
+ numericEmbeddingEntryCount: vectors.entries.filter((entry) => extractNumericEmbeddingShape(entry) !== null).length,
76
+ embeddingModels
77
+ };
78
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclawbrain/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "OpenClawBrain operator CLI package with install/status helpers, daemon controls, and import/export tooling.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",