recallnest 2.2.0 → 2.3.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.
- package/.env +4 -0
- package/CLAUDE.md +1 -1
- package/README.md +30 -5
- package/README_CN.md +30 -5
- package/config.json +55 -0
- package/connectors/examples/email-adapter.ts +73 -0
- package/connectors/examples/logs-adapter.ts +103 -0
- package/connectors/examples/rss-adapter.ts +95 -0
- package/logs/daily-recall.error.log +0 -0
- package/logs/daily-recall.log +60 -0
- package/logs/ingest-2026-04-11.log +110 -0
- package/logs/ingest-2026-04-12.log +90 -0
- package/logs/ingest-2026-04-13.log +87 -0
- package/logs/launchagent-stderr.log +0 -0
- package/logs/launchagent-stdout.log +0 -0
- package/package.json +1 -1
- package/src/cli.ts +30 -0
- package/src/connector-types.ts +57 -0
- package/src/conversation-importer.ts +25 -1
- package/src/data-checkup.ts +31 -1
- package/src/doctor.ts +29 -0
- package/src/ingest.ts +203 -0
- package/src/mcp-server.ts +2 -2
- package/src/obsidian-connector.ts +282 -0
- package/src/session-schema.ts +2 -2
- package/src/source-heartbeat.ts +108 -0
- package/.claude-plugin/CLAUDE.md +0 -29
- package/.claude-plugin/marketplace.json +0 -18
- package/.dockerignore +0 -11
- package/.github/workflows/ci.yml +0 -28
- package/.mcp.json +0 -9
- package/CHANGELOG.md +0 -51
- package/DEMO.md +0 -94
- package/Dockerfile +0 -20
- package/EVAL.md +0 -89
- package/FAILURES.md +0 -75
- package/OPERATIONS.md +0 -59
- package/ROADMAP.md +0 -245
- package/SKILL.md +0 -250
- package/assets/dashboard.png +0 -0
- package/assets/knowledge-graph.png +0 -0
- package/assets/recallnest-workbench.png +0 -0
- package/assets/screenshots/ui-full.png +0 -0
- package/assets/screenshots/ui-overview.png +0 -0
- package/assets/screenshots/ui-search.png +0 -0
- package/assets/ui/app.js +0 -1031
- package/assets/ui/index.html +0 -224
- package/assets/ui/styles.css +0 -781
- package/assets/wechat-qr.jpg +0 -0
- package/bun.lock +0 -337
- package/daily-reflections/2026-03-05.md +0 -15
- package/daily-reflections/2026-03-06.md +0 -15
- package/daily-reflections/2026-03-07.md +0 -7
- package/daily-reflections/2026-03-08.md +0 -34
- package/daily-reflections/2026-03-09.md +0 -35
- package/daily-reflections/2026-03-10.md +0 -36
- package/daily-reflections/2026-03-11.md +0 -35
- package/daily-reflections/2026-03-12.md +0 -36
- package/daily-reflections/2026-03-13.md +0 -35
- package/daily-reflections/2026-03-14.md +0 -35
- package/daily-reflections/2026-03-15.md +0 -35
- package/daily-reflections/2026-03-16.md +0 -41
- package/daily-reflections/2026-03-17.md +0 -10
- package/daily-reflections/2026-03-18.md +0 -10
- package/daily-reflections/2026-03-19.md +0 -10
- package/daily-reflections/2026-03-20.md +0 -10
- package/daily-reflections/2026-03-21.md +0 -10
- package/daily-reflections/2026-03-22.md +0 -10
- package/daily-reflections/2026-03-23.md +0 -10
- package/daily-reflections/2026-03-24.md +0 -10
- package/daily-reflections/2026-03-25.md +0 -32
- package/daily-reflections/2026-03-26.md +0 -37
- package/daily-reflections/2026-03-27.md +0 -35
- package/daily-reflections/2026-03-28.md +0 -35
- package/daily-reflections/2026-03-29.md +0 -35
- package/daily-reflections/2026-03-30.md +0 -36
- package/daily-reflections/2026-03-31.md +0 -35
- package/daily-reflections/2026-04-01.md +0 -35
- package/daily-reflections/2026-04-02.md +0 -35
- package/daily-reflections/2026-04-03.md +0 -37
- package/daily-reflections/2026-04-04.md +0 -37
- package/daily-reflections/2026-04-05.md +0 -35
- package/daily-reflections/2026-04-06.md +0 -36
- package/daily-reflections/2026-04-07.md +0 -35
- package/daily-reflections/2026-04-08.md +0 -35
- package/daily-reflections/2026-04-12.md +0 -35
- package/data/alias-map.example.json +0 -22
- package/docs/api-reference.md +0 -1291
- package/docs/architecture.md +0 -168
- package/docs/memory-boundary-contract.md +0 -226
- package/docs/memory-categories.md +0 -119
- package/docs/pipeline-audit-ultramemory.md +0 -177
- package/docs/plans/2026-03-08-query-expansion.md +0 -270
- package/docs/plans/2026-03-16-continuity-layer.md +0 -196
- package/docs/plans/2026-04-01-recall-boost.md +0 -100
- package/docs/plans/mcp-tiering-plan.md +0 -126
- package/docs/research/recall-quality-audit-2026-03-22.md +0 -153
- package/docs/self-evolution.md +0 -198
- package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +0 -782
- package/docs/superpowers/plans/2026-04-11-constructive-retrieval-emotion.md +0 -1195
- package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +0 -77
- package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +0 -95
- package/docs/superpowers/specs/2026-04-11-constructive-retrieval-emotion-design.md +0 -398
- package/eval/continuity/results-2026-03-16.md +0 -117
- package/eval/continuity/results-2026-03-19.md +0 -453
- package/eval/continuity/runbook.md +0 -110
- package/eval/continuity/seed-cases.md +0 -54
- package/eval/reports/2026-03-06-abstract-query-baseline.md +0 -96
- package/eval/reports/2026-03-06-aws-ssh-baseline.md +0 -82
- package/eval/reports/2026-03-06-baseline.md +0 -82
- package/eval/reports/query-expansion.md +0 -138
- package/glama.json +0 -6
- package/lm +0 -19
- package/plan-philosophy-upgrades.md +0 -363
- package/plan-product-upgrades.md +0 -155
- package/plan-v1.2-distributable.md +0 -105
- package/plan.md +0 -140
- package/research-memory-evolution.md +0 -440
- package/research-rl-agent-memory.md +0 -330
- package/scripts/archive-distilled-junk.ts +0 -116
- package/scripts/backfill-anchors.ts +0 -130
- package/scripts/backfill-l0l1l2.ts +0 -98
- package/scripts/blind-scan.ts +0 -588
- package/scripts/cleanup-step1-exact-dups.ts +0 -117
- package/scripts/cleanup-step2-template-dups.ts +0 -113
- package/scripts/cleanup-step3-stale-content.ts +0 -149
- package/scripts/cleanup-step4-orphan-scopes.ts +0 -131
- package/scripts/delete-distilled-junk.ts +0 -88
- package/scripts/diagnose-vector-search.ts +0 -132
- package/scripts/distill-facts.ts +0 -305
- package/scripts/health-check.ts +0 -343
- package/scripts/incremental-ingest.sh +0 -71
- package/scripts/migrate-language.ts +0 -75
- package/scripts/mlp-health-check.ts +0 -382
- package/scripts/pull-claude-desktop.ts +0 -515
- package/scripts/re-ingest-cc.sh +0 -66
- package/scripts/rebalance-memory-health.ts +0 -181
- package/scripts/run-desktop-ingest.sh +0 -11
- package/scripts/start-server.sh +0 -12
- package/scripts/verify-emotion-decay.ts +0 -148
- package/scripts/viz-dashboard.html +0 -423
- package/scripts/viz-export.ts +0 -703
- package/src/__tests__/access-tracker-novelty.test.ts +0 -228
- package/src/__tests__/activity-counter.test.ts +0 -96
- package/src/__tests__/admission-control.test.ts +0 -206
- package/src/__tests__/anchor-generator.test.ts +0 -67
- package/src/__tests__/auto-consolidation.test.ts +0 -168
- package/src/__tests__/auto-recall.test.ts +0 -131
- package/src/__tests__/babel-integration.test.ts +0 -139
- package/src/__tests__/batch-dedup.test.ts +0 -65
- package/src/__tests__/capture-engine.test.ts +0 -1144
- package/src/__tests__/capture-heuristic.test.ts +0 -171
- package/src/__tests__/cascade-forget.test.ts +0 -210
- package/src/__tests__/category-min-scores.test.ts +0 -33
- package/src/__tests__/cc8-cc1-essential-context.test.ts +0 -298
- package/src/__tests__/circuit-breaker.test.ts +0 -99
- package/src/__tests__/cluster-consolidation.test.ts +0 -712
- package/src/__tests__/confidence-metadata.test.ts +0 -125
- package/src/__tests__/confidence-tracker.test.ts +0 -249
- package/src/__tests__/conflict-advisor.test.ts +0 -206
- package/src/__tests__/conflict-escalation.test.ts +0 -149
- package/src/__tests__/conflict-lifecycle.test.ts +0 -83
- package/src/__tests__/conflict-output.test.ts +0 -85
- package/src/__tests__/conflict-store.test.ts +0 -374
- package/src/__tests__/consolidation-engine.test.ts +0 -181
- package/src/__tests__/constructive-retrieval.test.ts +0 -509
- package/src/__tests__/context-collapse-renderer.test.ts +0 -214
- package/src/__tests__/context-composer-pins.test.ts +0 -64
- package/src/__tests__/context-composer-task-selection.test.ts +0 -24
- package/src/__tests__/context-reconstructor.test.ts +0 -65
- package/src/__tests__/context-renderer.test.ts +0 -91
- package/src/__tests__/continuity-eval.test.ts +0 -275
- package/src/__tests__/continuity-schema.test.ts +0 -97
- package/src/__tests__/conversation-importer.test.ts +0 -692
- package/src/__tests__/core-recall-eval.test.ts +0 -235
- package/src/__tests__/core-summary.test.ts +0 -109
- package/src/__tests__/data-checkup.test.ts +0 -225
- package/src/__tests__/decay-exemption.test.ts +0 -84
- package/src/__tests__/dedup-actions.test.ts +0 -58
- package/src/__tests__/dedup-guard.test.ts +0 -39
- package/src/__tests__/deterministic-id.test.ts +0 -39
- package/src/__tests__/distill-lock.test.ts +0 -176
- package/src/__tests__/doctor.test.ts +0 -303
- package/src/__tests__/dream-pipeline.test.ts +0 -232
- package/src/__tests__/drill-down.test.ts +0 -108
- package/src/__tests__/embedder.test.ts +0 -122
- package/src/__tests__/emotion-decay.test.ts +0 -46
- package/src/__tests__/emotion-detector.test.ts +0 -56
- package/src/__tests__/emotion-phase1-integration.test.ts +0 -153
- package/src/__tests__/emotion-retrieval.test.ts +0 -56
- package/src/__tests__/entity-resolver.test.ts +0 -58
- package/src/__tests__/ethics-layer.test.ts +0 -476
- package/src/__tests__/event-segmenter.test.ts +0 -153
- package/src/__tests__/feature-flags-integration.test.ts +0 -54
- package/src/__tests__/frequency-tracker.test.ts +0 -113
- package/src/__tests__/graph-export.test.ts +0 -489
- package/src/__tests__/hotness-blend.test.ts +0 -76
- package/src/__tests__/ingest.test.ts +0 -360
- package/src/__tests__/interference-detector.test.ts +0 -203
- package/src/__tests__/kg-extractor.test.ts +0 -184
- package/src/__tests__/kg-store.test.ts +0 -198
- package/src/__tests__/llm-consolidation.test.ts +0 -226
- package/src/__tests__/mcp-efficiency.test.ts +0 -288
- package/src/__tests__/memory-boundaries.test.ts +0 -237
- package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +0 -243
- package/src/__tests__/memory-evolution.test.ts +0 -271
- package/src/__tests__/memory-health-rebalance.test.ts +0 -144
- package/src/__tests__/memory-lint.test.ts +0 -271
- package/src/__tests__/memory-output.test.ts +0 -215
- package/src/__tests__/multi-vector.test.ts +0 -242
- package/src/__tests__/narrative-architecture.test.ts +0 -456
- package/src/__tests__/pending-review.test.ts +0 -77
- package/src/__tests__/post-retrieval-filter.test.ts +0 -178
- package/src/__tests__/ppr-traversal.test.ts +0 -256
- package/src/__tests__/prediction-engine.test.ts +0 -349
- package/src/__tests__/predictive-prospective-memory.test.ts +0 -416
- package/src/__tests__/preference-guard-smoke.test.ts +0 -211
- package/src/__tests__/preference-matcher.test.ts +0 -230
- package/src/__tests__/preference-slots.test.ts +0 -205
- package/src/__tests__/prospective-memory.test.ts +0 -283
- package/src/__tests__/query-entity-detector.test.ts +0 -171
- package/src/__tests__/query-expander-alias.test.ts +0 -89
- package/src/__tests__/query-expander.test.ts +0 -34
- package/src/__tests__/recall-governor.test.ts +0 -227
- package/src/__tests__/recall-mode.test.ts +0 -64
- package/src/__tests__/result-synthesizer.test.ts +0 -198
- package/src/__tests__/resume-context.test.ts +0 -4898
- package/src/__tests__/retrieval-trace.test.ts +0 -213
- package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
- package/src/__tests__/retroactive-boost.test.ts +0 -223
- package/src/__tests__/salience-scoring.test.ts +0 -106
- package/src/__tests__/scope-inventory.test.ts +0 -200
- package/src/__tests__/scope-policy.test.ts +0 -69
- package/src/__tests__/session-checkpoint.test.ts +0 -259
- package/src/__tests__/session-distiller.test.ts +0 -611
- package/src/__tests__/session-gc.test.ts +0 -215
- package/src/__tests__/skill-engine.test.ts +0 -546
- package/src/__tests__/skill-promotion.test.ts +0 -349
- package/src/__tests__/store-scope-audit.test.ts +0 -81
- package/src/__tests__/supersede-chain.test.ts +0 -154
- package/src/__tests__/temporal-parser.test.ts +0 -241
- package/src/__tests__/temporal-validity.test.ts +0 -160
- package/src/__tests__/term-registry.test.ts +0 -121
- package/src/__tests__/tool-output-compressor.test.ts +0 -133
- package/src/__tests__/topic-tag.test.ts +0 -113
- package/src/__tests__/trusted-memory.test.ts +0 -828
- package/src/__tests__/version-manager.test.ts +0 -213
- package/src/__tests__/workflow-observation.test.ts +0 -400
- package/src/__tests__/write-verifier.test.ts +0 -122
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import lancedb from "@lancedb/lancedb";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
buildMemoryHealthRebalancePlan,
|
|
5
|
-
summarizeMemoryHealthPlans,
|
|
6
|
-
} from "../src/memory-health-rebalance.js";
|
|
7
|
-
|
|
8
|
-
const TABLE_NAME = "memories";
|
|
9
|
-
const DEFAULT_DB_PATH = "./data/lancedb";
|
|
10
|
-
const DEFAULT_BATCH_SIZE = 2000;
|
|
11
|
-
|
|
12
|
-
interface MemoryUpdateRow {
|
|
13
|
-
id: string;
|
|
14
|
-
text: string;
|
|
15
|
-
vector: Iterable<number>;
|
|
16
|
-
category: string;
|
|
17
|
-
scope: string;
|
|
18
|
-
importance: number;
|
|
19
|
-
timestamp: number;
|
|
20
|
-
metadata?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function escapeSqlLiteral(value: string): string {
|
|
24
|
-
return value.replace(/'/g, "''");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function formatPercent(count: number, total: number): string {
|
|
28
|
-
if (total <= 0) return "0.0%";
|
|
29
|
-
return `${((count / total) * 100).toFixed(1)}%`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function parseArgs(argv: string[]): {
|
|
33
|
-
dbPath: string;
|
|
34
|
-
batchSize: number;
|
|
35
|
-
apply: boolean;
|
|
36
|
-
optimize: boolean;
|
|
37
|
-
} {
|
|
38
|
-
const positional: string[] = [];
|
|
39
|
-
let batchSize = DEFAULT_BATCH_SIZE;
|
|
40
|
-
let apply = false;
|
|
41
|
-
let optimize = true;
|
|
42
|
-
|
|
43
|
-
for (const arg of argv) {
|
|
44
|
-
if (arg === "--apply") {
|
|
45
|
-
apply = true;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (arg === "--skip-optimize") {
|
|
49
|
-
optimize = false;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (arg.startsWith("--batch-size=")) {
|
|
53
|
-
const value = Number(arg.slice("--batch-size=".length));
|
|
54
|
-
if (Number.isFinite(value) && value > 0) {
|
|
55
|
-
batchSize = Math.floor(value);
|
|
56
|
-
}
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
positional.push(arg);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
dbPath: positional[0] || DEFAULT_DB_PATH,
|
|
64
|
-
batchSize,
|
|
65
|
-
apply,
|
|
66
|
-
optimize,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function loadPlanningRows(table: Awaited<ReturnType<typeof lancedb.connect>> extends { openTable(name: string): infer T } ? Awaited<T> : never) {
|
|
71
|
-
return await table
|
|
72
|
-
.query()
|
|
73
|
-
.select(["id", "importance", "timestamp", "metadata"])
|
|
74
|
-
.toArray() as Array<{ id: string; importance: number; timestamp: number; metadata?: string }>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async function loadBatchRows(
|
|
78
|
-
table: Awaited<ReturnType<typeof lancedb.connect>> extends { openTable(name: string): infer T } ? Awaited<T> : never,
|
|
79
|
-
ids: string[],
|
|
80
|
-
): Promise<MemoryUpdateRow[]> {
|
|
81
|
-
const where = `id IN (${ids.map((id) => `'${escapeSqlLiteral(id)}'`).join(", ")})`;
|
|
82
|
-
return await table
|
|
83
|
-
.query()
|
|
84
|
-
.where(where)
|
|
85
|
-
.select(["id", "text", "vector", "category", "scope", "importance", "timestamp", "metadata"])
|
|
86
|
-
.toArray() as MemoryUpdateRow[];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function main() {
|
|
90
|
-
const { dbPath, batchSize, apply, optimize } = parseArgs(process.argv.slice(2));
|
|
91
|
-
|
|
92
|
-
console.log(`\n🛠️ Memory health rebalance`);
|
|
93
|
-
console.log(`📂 DB path: ${dbPath}`);
|
|
94
|
-
console.log(`📦 Batch size: ${batchSize}`);
|
|
95
|
-
console.log(`🧪 Mode: ${apply ? "apply" : "dry-run"}\n`);
|
|
96
|
-
|
|
97
|
-
const db = await lancedb.connect(dbPath);
|
|
98
|
-
const table = await db.openTable(TABLE_NAME);
|
|
99
|
-
|
|
100
|
-
console.log("⏳ Loading planning rows...");
|
|
101
|
-
const planningRows = await loadPlanningRows(table);
|
|
102
|
-
const accessCounts = planningRows.map((row) =>
|
|
103
|
-
buildMemoryHealthRebalancePlan(row, {
|
|
104
|
-
maxAccessCount: 1,
|
|
105
|
-
minTimestamp: row.timestamp,
|
|
106
|
-
maxTimestamp: row.timestamp,
|
|
107
|
-
}).accessCount
|
|
108
|
-
);
|
|
109
|
-
const effectiveMaxAccessCount = Math.max(1, ...accessCounts);
|
|
110
|
-
const minTimestamp = Math.min(...planningRows.map((row) => row.timestamp));
|
|
111
|
-
const maxTimestamp = Math.max(...planningRows.map((row) => row.timestamp));
|
|
112
|
-
const plans = planningRows.map((row) =>
|
|
113
|
-
buildMemoryHealthRebalancePlan(row, {
|
|
114
|
-
maxAccessCount: effectiveMaxAccessCount,
|
|
115
|
-
minTimestamp,
|
|
116
|
-
maxTimestamp,
|
|
117
|
-
})
|
|
118
|
-
);
|
|
119
|
-
const summary = summarizeMemoryHealthPlans(plans);
|
|
120
|
-
|
|
121
|
-
console.log(`✅ Planned ${summary.totalRows.toLocaleString()} rows`);
|
|
122
|
-
console.log(` dead memory rows : ${summary.deadMemoryRows.toLocaleString()} (${formatPercent(summary.deadMemoryRows, summary.totalRows)})`);
|
|
123
|
-
console.log(` tier backfills : ${summary.tierBackfills.toLocaleString()} (${formatPercent(summary.tierBackfills, summary.totalRows)})`);
|
|
124
|
-
console.log(` tier changes : ${summary.tierChanges.toLocaleString()} (${formatPercent(summary.tierChanges, summary.totalRows)})`);
|
|
125
|
-
console.log(` importance changes : ${summary.importanceChanges.toLocaleString()} (${formatPercent(summary.importanceChanges, summary.totalRows)})`);
|
|
126
|
-
console.log(` rows to rewrite : ${summary.changedRows.toLocaleString()} (${formatPercent(summary.changedRows, summary.totalRows)})`);
|
|
127
|
-
|
|
128
|
-
if (!apply) {
|
|
129
|
-
console.log("\nDry run only. Re-run with --apply after backing up the LanceDB directory.");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const changedPlans = plans.filter((plan) => plan.changed);
|
|
134
|
-
const planById = new Map(changedPlans.map((plan) => [plan.id, plan]));
|
|
135
|
-
|
|
136
|
-
let processed = 0;
|
|
137
|
-
for (let start = 0; start < changedPlans.length; start += batchSize) {
|
|
138
|
-
const batchPlans = changedPlans.slice(start, start + batchSize);
|
|
139
|
-
const ids = batchPlans.map((plan) => plan.id);
|
|
140
|
-
const rows = await loadBatchRows(table, ids);
|
|
141
|
-
const mergeRows = rows.map((row) => {
|
|
142
|
-
const plan = planById.get(row.id);
|
|
143
|
-
if (!plan) {
|
|
144
|
-
throw new Error(`Missing plan for row ${row.id}`);
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
id: row.id,
|
|
148
|
-
text: row.text,
|
|
149
|
-
vector: Array.from(row.vector),
|
|
150
|
-
category: row.category,
|
|
151
|
-
scope: row.scope,
|
|
152
|
-
importance: plan.nextImportance,
|
|
153
|
-
timestamp: row.timestamp,
|
|
154
|
-
metadata: JSON.stringify(plan.nextMetadata),
|
|
155
|
-
};
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
await table
|
|
159
|
-
.mergeInsert("id")
|
|
160
|
-
.whenMatchedUpdateAll()
|
|
161
|
-
.execute(mergeRows, { timeoutMs: 120_000 });
|
|
162
|
-
|
|
163
|
-
processed += mergeRows.length;
|
|
164
|
-
console.log(` batch ${Math.floor(start / batchSize) + 1}/${Math.ceil(changedPlans.length / batchSize)}: ${processed.toLocaleString()}/${changedPlans.length.toLocaleString()} rows`);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (optimize) {
|
|
168
|
-
console.log("\n⏳ Optimizing Lance table after batched rewrites...");
|
|
169
|
-
await table.optimize();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
console.log("\n✅ Memory health rebalance complete");
|
|
173
|
-
console.log(` dead memory rows kept but downgraded: ${summary.deadMemoryRows.toLocaleString()}`);
|
|
174
|
-
console.log(` tier backfills applied : ${summary.tierBackfills.toLocaleString()}`);
|
|
175
|
-
console.log(` importance updates applied : ${summary.importanceChanges.toLocaleString()}`);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
main().catch((error) => {
|
|
179
|
-
console.error(error);
|
|
180
|
-
process.exitCode = 1;
|
|
181
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# 后台运行 desktop ingest,关窗口也不中断
|
|
3
|
-
# 日志输出到 data/desktop-ingest.log
|
|
4
|
-
|
|
5
|
-
cd "$(dirname "$0")/.."
|
|
6
|
-
LOG="data/desktop-ingest.log"
|
|
7
|
-
|
|
8
|
-
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始导入 Desktop 对话..." > "$LOG"
|
|
9
|
-
bun run src/cli.ts ingest --source desktop >> "$LOG" 2>&1
|
|
10
|
-
echo "" >> "$LOG"
|
|
11
|
-
echo "$(date '+%Y-%m-%d %H:%M:%S') 导入完成" >> "$LOG"
|
package/scripts/start-server.sh
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# RecallNest MCP Server startup script
|
|
3
|
-
# Handles first-run bun install automatically
|
|
4
|
-
set -e
|
|
5
|
-
|
|
6
|
-
PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
7
|
-
|
|
8
|
-
if [ ! -d "$PLUGIN_DIR/node_modules" ]; then
|
|
9
|
-
cd "$PLUGIN_DIR" && bun install --frozen-lockfile --silent 2>/dev/null
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
exec bun run "$PLUGIN_DIR/src/mcp-server.ts"
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* Phase 1 Manual Verification: Emotional Valence in Decay
|
|
4
|
-
*
|
|
5
|
-
* Demonstrates:
|
|
6
|
-
* 1. detectEmotion → salience + source fields
|
|
7
|
-
* 2. adjustHalfLifeForEmotion → emotional memories get longer half-life
|
|
8
|
-
* 3. computeDecayScore → emotion-aware weights
|
|
9
|
-
* 4. End-to-end: emotional memory scores higher than neutral at same age
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { detectEmotion } from "../src/emotion-detector.js";
|
|
13
|
-
import { adjustHalfLifeForEmotion, computeArousalBoost, weibullDecay, resolveTier } from "../src/decay-engine.js";
|
|
14
|
-
import { computeDecayScore, type EvolutionMetadata } from "../src/memory-evolution.js";
|
|
15
|
-
import { parseEmotion } from "../src/memory-schema.js";
|
|
16
|
-
|
|
17
|
-
// Force emotion flag on for verification
|
|
18
|
-
process.env.RECALLNEST_EMOTION_SCORING = "true";
|
|
19
|
-
|
|
20
|
-
const DIVIDER = "─".repeat(60);
|
|
21
|
-
|
|
22
|
-
// ── 1. detectEmotion: salience + source ──────────────────────
|
|
23
|
-
|
|
24
|
-
console.log("\n" + DIVIDER);
|
|
25
|
-
console.log("1️⃣ detectEmotion: salience + source");
|
|
26
|
-
console.log(DIVIDER);
|
|
27
|
-
|
|
28
|
-
const samples = [
|
|
29
|
-
{ label: "愤怒调试", text: "CRITICAL BUG! 这个问题搞了三天还是崩溃,太frustrating了!" },
|
|
30
|
-
{ label: "成功修复", text: "Finally fixed it! Everything works perfectly, all tests pass!" },
|
|
31
|
-
{ label: "中性日志", text: "Updated the config file and ran the migration script." },
|
|
32
|
-
{ label: "中文负面", text: "这个方案不好用,不开心,又失败了" },
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
for (const s of samples) {
|
|
36
|
-
const e = detectEmotion(s.text);
|
|
37
|
-
console.log(`\n [${s.label}]`);
|
|
38
|
-
console.log(` text: "${s.text.slice(0, 50)}..."`);
|
|
39
|
-
console.log(` valence: ${e.valence.toFixed(2)} arousal: ${e.arousal.toFixed(2)} label: ${e.label}`);
|
|
40
|
-
console.log(` salience: ${e.salience?.toFixed(3)} source: ${e.source}`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ── 2. Half-life adjustment ──────────────────────────────────
|
|
44
|
-
|
|
45
|
-
console.log("\n" + DIVIDER);
|
|
46
|
-
console.log("2️⃣ adjustHalfLifeForEmotion: half-life extension");
|
|
47
|
-
console.log(DIVIDER);
|
|
48
|
-
|
|
49
|
-
const baseHL = 60; // 60 days
|
|
50
|
-
for (const s of samples) {
|
|
51
|
-
const e = detectEmotion(s.text);
|
|
52
|
-
const adjustedHL = adjustHalfLifeForEmotion(baseHL, e);
|
|
53
|
-
const boost = computeArousalBoost(e);
|
|
54
|
-
const delta = ((adjustedHL / baseHL - 1) * 100).toFixed(1);
|
|
55
|
-
console.log(`\n [${s.label}]`);
|
|
56
|
-
console.log(` base HL: ${baseHL}d → adjusted: ${adjustedHL.toFixed(1)}d (+${delta}%)`);
|
|
57
|
-
console.log(` arousal boost: ${boost.toFixed(3)}x`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ── 3. Weibull decay comparison at 30d, 60d, 90d ────────────
|
|
61
|
-
|
|
62
|
-
console.log("\n" + DIVIDER);
|
|
63
|
-
console.log("3️⃣ Weibull decay: emotional vs neutral at different ages");
|
|
64
|
-
console.log(DIVIDER);
|
|
65
|
-
|
|
66
|
-
const emotionalText = "CRITICAL BUG! 这个问题搞了三天还是崩溃,太frustrating了!";
|
|
67
|
-
const neutralText = "Updated the config file and ran the migration script.";
|
|
68
|
-
const emotionalEmo = detectEmotion(emotionalText);
|
|
69
|
-
const neutralEmo = detectEmotion(neutralText);
|
|
70
|
-
const emotionalHL = adjustHalfLifeForEmotion(baseHL, emotionalEmo);
|
|
71
|
-
const neutralHL = adjustHalfLifeForEmotion(baseHL, neutralEmo);
|
|
72
|
-
const emotionalBoost = computeArousalBoost(emotionalEmo);
|
|
73
|
-
const neutralBoost = computeArousalBoost(neutralEmo);
|
|
74
|
-
|
|
75
|
-
console.log(`\n ${"Age".padEnd(8)} ${"Emotional".padEnd(14)} ${"Neutral".padEnd(14)} ${"Δ advantage".padEnd(14)}`);
|
|
76
|
-
for (const ageDays of [7, 30, 60, 90, 120]) {
|
|
77
|
-
const emoDecay = weibullDecay(ageDays, emotionalHL, "working") * emotionalBoost;
|
|
78
|
-
const neuDecay = weibullDecay(ageDays, neutralHL, "working") * neutralBoost;
|
|
79
|
-
const advantage = ((emoDecay / neuDecay - 1) * 100).toFixed(1);
|
|
80
|
-
console.log(` ${(ageDays + "d").padEnd(8)} ${emoDecay.toFixed(4).padEnd(14)} ${neuDecay.toFixed(4).padEnd(14)} +${advantage}%`);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// ── 4. computeDecayScore: full formula comparison ────────────
|
|
84
|
-
|
|
85
|
-
console.log("\n" + DIVIDER);
|
|
86
|
-
console.log("4️⃣ computeDecayScore: emotion-aware weights (0.15/0.25/0.45/0.15)");
|
|
87
|
-
console.log(DIVIDER);
|
|
88
|
-
|
|
89
|
-
const now = Date.now();
|
|
90
|
-
const makeEvo = (ageDays: number, accessCount: number): EvolutionMetadata => ({
|
|
91
|
-
status: "active",
|
|
92
|
-
version: 1,
|
|
93
|
-
accessCount,
|
|
94
|
-
lastAccessedAt: now - 7 * 86_400_000,
|
|
95
|
-
supersededBy: null,
|
|
96
|
-
supersedes: null,
|
|
97
|
-
evolutionNote: null,
|
|
98
|
-
consolidatedInto: null,
|
|
99
|
-
contributedToPattern: null,
|
|
100
|
-
sourceMemories: [],
|
|
101
|
-
validFrom: now - ageDays * 86_400_000,
|
|
102
|
-
validUntil: null,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const scenarios = [
|
|
106
|
-
{ label: "新记忆(7d), 3次访问, importance=0.7", age: 7, access: 3, importance: 0.7 },
|
|
107
|
-
{ label: "旧记忆(60d), 3次访问, importance=0.7", age: 60, access: 3, importance: 0.7 },
|
|
108
|
-
{ label: "很旧(120d), 低访问, importance=0.5", age: 120, access: 1, importance: 0.5 },
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
for (const sc of scenarios) {
|
|
112
|
-
const evo = makeEvo(sc.age, sc.access);
|
|
113
|
-
const emotionalMeta = JSON.stringify({
|
|
114
|
-
emotion: detectEmotion(emotionalText),
|
|
115
|
-
});
|
|
116
|
-
const neutralMeta = JSON.stringify({
|
|
117
|
-
emotion: detectEmotion(neutralText),
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const emoScore = computeDecayScore(evo, sc.importance, now, emotionalMeta);
|
|
121
|
-
const neuScore = computeDecayScore(evo, sc.importance, now, neutralMeta);
|
|
122
|
-
const noMetaScore = computeDecayScore(evo, sc.importance, now); // backward compat
|
|
123
|
-
|
|
124
|
-
console.log(`\n [${sc.label}]`);
|
|
125
|
-
console.log(` emotional: ${emoScore.toFixed(4)}`);
|
|
126
|
-
console.log(` neutral: ${neuScore.toFixed(4)}`);
|
|
127
|
-
console.log(` no-meta: ${noMetaScore.toFixed(4)} (backward compat, base weights)`);
|
|
128
|
-
console.log(` Δ emotion: +${((emoScore / neuScore - 1) * 100).toFixed(1)}% vs neutral`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// ── 5. parseEmotion backward compat ──────────────────────────
|
|
132
|
-
|
|
133
|
-
console.log("\n" + DIVIDER);
|
|
134
|
-
console.log("5️⃣ parseEmotion: backward compatibility");
|
|
135
|
-
console.log(DIVIDER);
|
|
136
|
-
|
|
137
|
-
const oldMeta = JSON.stringify({ emotion: { valence: 0.5, arousal: 0.3, label: "positive" } }); // no salience/source
|
|
138
|
-
const newMeta = JSON.stringify({ emotion: { valence: 0.5, arousal: 0.3, label: "positive", salience: 0.4, source: "keyword" } });
|
|
139
|
-
const noEmoMeta = JSON.stringify({ tier: "working" });
|
|
140
|
-
|
|
141
|
-
console.log(`\n old format (no salience): ${JSON.stringify(parseEmotion(oldMeta))}`);
|
|
142
|
-
console.log(` new format (with salience): ${JSON.stringify(parseEmotion(newMeta))}`);
|
|
143
|
-
console.log(` no emotion field: ${parseEmotion(noEmoMeta)}`);
|
|
144
|
-
console.log(` undefined: ${parseEmotion(undefined)}`);
|
|
145
|
-
|
|
146
|
-
console.log("\n" + DIVIDER);
|
|
147
|
-
console.log("✅ Phase 1 Verification Complete");
|
|
148
|
-
console.log(DIVIDER + "\n");
|