@unblocklabs/unblock-memory 0.9.0 → 0.10.0

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.
@@ -17,8 +17,8 @@ export declare class RetrievalTelemetry {
17
17
  [k: string]: {
18
18
  calls: number;
19
19
  outcomes: {
20
- ok?: number | undefined;
21
20
  cancelled?: number | undefined;
21
+ ok?: number | undefined;
22
22
  partial?: number | undefined;
23
23
  skipped?: number | undefined;
24
24
  failed?: number | undefined;
@@ -26,8 +26,11 @@ settings; a rotated credential file is reread without a restart.
26
26
  | Inside Out | `insideOut.enabled`; opts in all retained channels | No inference | Failed reviews are recorded and retried; successes stay cached |
27
27
  | Clustering | Configured local `analysis.executable` | Unchanged | Unchanged; worker failures do not disable ordinary search |
28
28
 
29
- Whisperers, people storage, the primer and audits default off. `typesafe.enabled` defaults true but does not
30
- enable any feature; `sentimentEnabled` defaults true only **within an enabled
29
+ Skill Whisperer turns on by default once a `skills` corpus is configured; without
30
+ one it registers no hook and reports inactive.
31
+ Memory/People Whisperers, people storage, the primer and audits default off.
32
+ `typesafe.enabled` defaults true but does not enable those opt-in features;
33
+ `sentimentEnabled` defaults true only **within an enabled
31
34
  response audit**. `peoplePrimer` controls automatic dossier-save review;
32
35
  `evidenceReview` is a different advisory tool. Disabling people injection does
33
36
  not disable people tools/storage or erase dossiers.
@@ -217,7 +220,7 @@ contract; these tables explain their effects.
217
220
  | `typesafe.apiKey` | Unset | Explicit inline key; mutually exclusive with key file; prefer file |
218
221
  | `typesafe.apiKeyFile` | Unset | Absolute raw-key or dotenv file, reread at credential resolution; explicit missing file never falls back to a different key |
219
222
  | `typesafe.timeoutMs` | `1500` | 1–10,000 per request for Skill/Memory Whisperer, quality/claim/cluster review and response audit; **primer and dossier save use `peoplePrimer.timeoutMs` and Safety Whisperer uses `safetyWhisperer.timeoutMs` instead** |
220
- | `skillWhisperer.enabled` | `false` | Requires explicit skills corpus and appropriate host hook access; fixed 3-second total deadline |
223
+ | `skillWhisperer.enabled` | `true` | Active only with a `skills` corpus (otherwise resolved to `false`, with no hook or host warning) and appropriate host hook access; fixed 3-second total deadline; `false` opts out |
221
224
  | `skillWhisperer.historyMessages` | `5` | Nonnegative integer; prior visible messages used for routing |
222
225
  | `skillWhisperer.minScore` | `0.5` | 0–1, **local vector fallback only**, ignored for TypeSafe shortlist admission |
223
226
  | `skillWhisperer.cooldownTurns` | `10` | Nonnegative user-turn count; no fallback to weaker cooling-down alternatives |
@@ -549,15 +552,18 @@ change memories, retrieval, prompts, or dossiers.
549
552
  "enabled": true,
550
553
  "intervalMinutes": 1440,
551
554
  "maxInteractions": 100,
552
- "maxContextTokens": 30000
555
+ "maxContextTokens": 30000,
556
+ "baselineMinInteractions": 20
553
557
  }
554
558
  }
555
559
  ```
556
560
 
557
561
  Defaults: disabled; daily cadence; at most 100 attempted reviews per run; estimated
558
562
  30,000-token context budget, leaving room for questions under Jev's 32k
559
- state-plus-longest-question limit. `intervalMinutes: 0` is manual-only. The shared
560
- `typesafe` settings supply Jev credentials and request timeout.
563
+ state-plus-longest-question limit. `intervalMinutes: 0` makes inference manual-only;
564
+ local baselines still refresh daily and on Gateway startup when Inside Out is enabled.
565
+ `baselineMinInteractions` defaults to 20 (1–10,000) for each comparison population.
566
+ The shared `typesafe` settings supply Jev credentials and request timeout.
561
567
 
562
568
  **Enabling this approves sending visible human/assistant conversation text across
563
569
  all retained channels to TypeSafe.** System messages, tool bodies, thinking blocks,
@@ -582,11 +588,15 @@ openclaw memory-emotions link-people --agent main
582
588
  openclaw memory-emotions link-people --agent main --repair-identities
583
589
  openclaw memory-emotions run --agent main --session SESSION_ID
584
590
  openclaw memory-emotions export --agent main --session SESSION_ID
591
+ openclaw memory-emotions baseline-refresh --agent main
592
+ openclaw memory-emotions baselines --agent main --person PERSON_ID
593
+ openclaw memory-emotions export --agent main --person PERSON_ID --deviation-history
594
+ openclaw memory-emotions baseline-refresh --agent main --recompare
585
595
  ```
586
596
 
587
597
  `run` handles backfill and new interactions through the same bounded pass. Repeat
588
- it until `reviewed` and `failed` are zero to finish backfill. Gateway startup also
589
- runs one pass, then repeats at the configured interval. Successful results are
598
+ it until `reviewed` and `failed` are zero to finish backfill. With automatic inference
599
+ enabled, Gateway startup also runs one pass, then repeats at the configured interval. Successful results are
590
600
  cached; new interactions take priority over retries. Request failures retry after
591
601
  an hour when the pass has remaining capacity, or immediately with `--retry`.
592
602
  Oversized context failures require explicit `--retry`, for example after increasing
@@ -645,13 +655,109 @@ changed or removed mappings; by default it never reads transcripts. Its explicit
645
655
  `--repair-identities` option reads sources owning unlinked reviews and repairs
646
656
  their channel, sender ID and human key from persisted metadata before linking.
647
657
  Neither mode calls Jev or changes scores, timestamps, review IDs or checkpoints.
648
- Unmatched identities stay null. Exports include `person_id`.
658
+ Unmatched identities stay null. Exports include `person_id` and `personal_deviation`.
649
659
  `export` emits all matching rows as JSON, including errors. `report` averages
650
660
  successful rows by human, UTC day/week, rubric, and model; counts are the denominator.
651
- Both accept `--session`, `--sender`, `--since YYYY-MM-DD`, `--emotion`, and `--min`. `--sender`
661
+ Both accept `--person`, `--session`, `--sender`, `--since YYYY-MM-DD`, `--emotion`, and `--min`. `--sender`
652
662
  matches exact sender IDs across channels; use exported `human_key` for precise
653
663
  account-specific analysis. These commands are read-only and never invoke Jev.
654
664
 
665
+ ### Person-relative baselines and deviations
666
+
667
+ Inside Out keeps analytics beside PeopleSQL in the same `unblock-memory.sqlite`,
668
+ linked by its existing `person_id`. `person_emotion_baselines` holds one snapshot
669
+ per person, rubric, model and completed week; `inside_out_deviations` holds
670
+ individual assessments. They are separate from dossier fields, recognition blurbs
671
+ and searchable memory. PeopleSQL identities must already exist; Inside Out does not
672
+ create people or guess links. Statistics are per agent's retained grades, not
673
+ fleet-wide aggregates.
674
+
675
+ Weeks run Monday 00:00 UTC to the next Monday, with an exclusive end. Each stored
676
+ week keeps, per emotion, the exact sample count, sum, minimum and maximum, plus the
677
+ distribution in 0.01-wide bins (at most 101 values), so a snapshot stays small
678
+ however much history accumulates. Reports show weekly and cumulative sample counts,
679
+ mean, minimum, maximum, p10, median, p90 and the binned distribution; cumulative
680
+ values are computed from all earlier stored weeks when read. Means, minimums and
681
+ maximums are exact; quantiles use bin values. Completed empty weeks are logged with
682
+ zero weekly observations. Rubrics and models have separate populations.
683
+
684
+ For each graded reply, `personal_deviation` compares its raw probabilities to that
685
+ person's **preceding completed weeks**, excluding the reply's entire current week
686
+ and future interactions. Both cumulative history and the immediately preceding
687
+ week are reported. Each emotion includes:
688
+
689
+ - `delta`: signed difference from the person's exact baseline mean.
690
+ - `percentile`: empirical rank from 0 to 1 within 0.01-wide bins; grades in the
691
+ same bin are ties and take the midpoint.
692
+ - `unusualness`: `abs(2 * percentile - 1)`, from 0 at the middle to 1 at the extremes.
693
+ This is a rank-derived signal, **not a probability or emotional intensity**.
694
+
695
+ For example, a joy probability of 0.8 can be routine for someone whose prior grades
696
+ are consistently 0.8, and unusual for someone whose prior grades are 0.1. This does
697
+ not establish their personality, mental state, or the agent's quality. Counts below
698
+ `baselineMinInteractions` produce `insufficient_history` with null emotion metrics,
699
+ independently for weekly and cumulative comparisons. Unlinked people, missing or
700
+ future timestamps and failed grades have explicit statuses; they are never neutral
701
+ scores. Exports before the first local assessment show `not_compared`.
702
+
703
+ `run` refreshes snapshots after grading new replies. Both grading and daily local
704
+ refreshes update exact PeopleSQL links before aggregating or assessing new replies.
705
+ Historical aggregation runs in a worker thread and commits in short batches, so the
706
+ Gateway event loop stays responsive and other writers to `unblock-memory.sqlite`
707
+ wait for one batch at most, never a whole refresh. Gateway shutdown cancels an
708
+ active refresh; the next one resumes, and repeating a refresh never duplicates
709
+ records. If the refresh after grading fails, `run` still returns its counts with a
710
+ `baselineError` (the Gateway logs a warning); saved grades are unaffected.
711
+ `link-people` also refreshes analytics. `baseline-refresh` does this without loading
712
+ transcripts, calling Jev, or requiring TypeSafe credentials. `baselines` reads
713
+ weekly snapshots, newest first, with optional `--person`, `--since YYYY-MM-DD`
714
+ (inclusive UTC week-end) and `--limit` (1–1,000 weeks, default 100).
715
+
716
+ Snapshots always reflect the currently linked grades. A late historical grade, a
717
+ retry, a relink or removed identity evidence rewrites the affected week and every
718
+ later week of that population in place, and a population with no linked grades left
719
+ loses its snapshots; earlier revisions are not kept. A snapshot `id` addresses its
720
+ whole cumulative population, so returning to an earlier population restores the
721
+ earlier `id`.
722
+
723
+ Normal refreshes preserve an existing assessment of the same grade. Late historical
724
+ grades change snapshots but do not silently rewrite earlier comparisons.
725
+ Use `baseline-refresh --recompare` to append changed assessments after backfill,
726
+ identity or sample-policy changes; `export --deviation-history` includes the earlier
727
+ results and marks which match the current grade. Repeating an unchanged refresh
728
+ adds no duplicate records. Previously sparse or future-dated assessments also need
729
+ explicit re-comparison when their circumstances change.
730
+
731
+ `computed_at` and `assessedAt` record when these calculations actually occurred.
732
+ A backfilled comparison uses retained evidence from earlier interaction weeks, but
733
+ does not pretend that evidence had already been graded at the historical send time.
734
+ Baseline calculation requires no additional model calls and changes no raw emotion
735
+ judgments, dossiers, prompt injection, clustering or memory creation.
736
+
737
+ ### Deleting a person's emotion data
738
+
739
+ ```bash
740
+ openclaw memory-emotions purge --agent main --person PERSON_ID
741
+ openclaw memory-emotions purge --agent main --person PERSON_ID --grades
742
+ ```
743
+
744
+ `purge` deletes one person's weekly snapshots and their whole assessment history,
745
+ including assessments recorded while a reply was linked to them, and prints what it
746
+ removed. It makes no Jev calls.
747
+
748
+ - **Without `--grades`**, their raw grades stay, so the next refresh rebuilds
749
+ current snapshots and assessments from replies still linked to them. Use this
750
+ after correcting a misattributed identity.
751
+ - **With `--grades`**, it also erases the six probabilities of every reply currently
752
+ linked to that person and unlinks it. Each row stays as a tombstone with the error
753
+ `Purged by operator`, so `run` (including `--retry`) never sends that reply to Jev
754
+ again, `link-people` never relinks it, and refreshes skip it. This cannot be
755
+ undone; run `link-people` first so every reply from that person is linked.
756
+
757
+ Purging removes existing data only. While Inside Out stays enabled and the person's
758
+ identity remains in PeopleSQL, their new replies are graded and start a new
759
+ baseline. Soft-deleting a person in PeopleSQL does not remove Inside Out data.
760
+
655
761
  ## Storage, upgrades and recovery
656
762
 
657
763
  Each agent's state lives under the configured OpenClaw state directory, normally
package/docs/peoplesql.md CHANGED
@@ -9,6 +9,13 @@ store with `people.enabled`; enable injection separately with
9
9
  and automatic save review, not a maintenance scheduler. For independent setup
10
10
  examples, see the [configuration profiles](configuration.md#example-profiles).
11
11
 
12
+ [Inside Out baselines](configuration.md#person-relative-baselines-and-deviations)
13
+ reuse PeopleSQL's person IDs in separate analytics tables in the same database.
14
+ They retain weekly emotion-grade distributions and interaction deviations; none of
15
+ this analytics is written into dossiers or injected by People Whisperer. Deleting a
16
+ dossier or soft-deleting a person leaves it in place; use
17
+ [`memory-emotions purge`](configuration.md#deleting-a-persons-emotion-data).
18
+
12
19
  ## Optional People Dossier Primer
13
20
 
14
21
  `memory_people_prime({ personId, agentName? })` prepares evidence for an existing person;
package/docs/retrieval.md CHANGED
@@ -468,9 +468,11 @@ or raw exceptions; exact query text is not retained by this telemetry.
468
468
  ## Skill Whisperer
469
469
 
470
470
 
471
- Skill Whisperer is an optional semantic reminder for user turns. Configure one
472
- isolated `skills` corpus, set `skillWhisperer.enabled` to `true`, and authorize
473
- `plugins.entries.unblock-memory.hooks.allowConversationAccess`. The feature
471
+ Skill Whisperer is a semantic reminder for user turns. It turns on by default once
472
+ you configure one isolated `skills` corpus and authorize
473
+ `plugins.entries.unblock-memory.hooks.allowConversationAccess`. Without a skills
474
+ corpus it stays inactive: no prompt hook is registered and diagnostics report it
475
+ disabled. Set `skillWhisperer.enabled` to `false` to opt out. It
474
476
  embeds the current prompt plus the configured number of prior user/assistant
475
477
  messages, compares it with each configured skill's frontmatter `name` and
476
478
  `description`. With TypeSafe enabled and a key available, the top three valid
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "unblock-memory",
3
3
  "name": "Unblock Memory",
4
- "version": "0.9.0",
4
+ "version": "0.10.0",
5
5
  "description": "Indexes, retrieves, and analyzes configured workspace memory with existing QMD vectors.",
6
6
  "kind": "memory",
7
7
  "activation": { "onStartup": true },
@@ -124,7 +124,8 @@
124
124
  "enabled": { "type": "boolean", "default": false },
125
125
  "intervalMinutes": { "type": "integer", "minimum": 0, "maximum": 10080, "default": 1440 },
126
126
  "maxInteractions": { "type": "integer", "minimum": 1, "maximum": 10000, "default": 100 },
127
- "maxContextTokens": { "type": "integer", "minimum": 256, "maximum": 30000, "default": 30000 }
127
+ "maxContextTokens": { "type": "integer", "minimum": 256, "maximum": 30000, "default": 30000 },
128
+ "baselineMinInteractions": { "type": "integer", "minimum": 1, "maximum": 10000, "default": 20 }
128
129
  }
129
130
  },
130
131
  "extraction": {
@@ -348,13 +349,13 @@
348
349
  "type": "object",
349
350
  "additionalProperties": false,
350
351
  "properties": {
351
- "enabled": { "type": "boolean", "default": false },
352
+ "enabled": { "type": "boolean", "default": true, "description": "Takes effect only when a corpus with kind \"skills\" is configured." },
352
353
  "historyMessages": { "type": "integer", "minimum": 0, "default": 5 },
353
354
  "minScore": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.5 },
354
355
  "cooldownTurns": { "type": "integer", "minimum": 0, "default": 10 }
355
356
  },
356
357
  "default": {
357
- "enabled": false,
358
+ "enabled": true,
358
359
  "historyMessages": 5,
359
360
  "minScore": 0.5,
360
361
  "cooldownTurns": 10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unblocklabs/unblock-memory",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Workspace-native memory for OpenClaw, powered by QMD",
5
5
  "type": "module",
6
6
  "license": "MIT",