dsh-memu-memory 1.2.0 → 1.2.2
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/AGENTS.md +1 -1
- package/README.md +19 -8
- package/README.zh.md +12 -6
- package/docs/contributing.md +16 -3
- package/docs/env-and-commands.md +8 -0
- package/docs/host-api.md +3 -1
- package/docs/memory-semantics.md +21 -2
- package/docs/troubleshooting.md +42 -3
- package/lib/activity-log.js +22 -5
- package/lib/backup.js +24 -2
- package/lib/binding-diagnostics.js +3 -3
- package/lib/client.js +1610 -117
- package/lib/consolidation-worker.js +68 -17
- package/lib/curator-evidence.js +131 -0
- package/lib/curator-policy.js +81 -0
- package/lib/curator.js +1299 -83
- package/lib/cycle.js +3 -0
- package/lib/embedding-download.js +39 -4
- package/lib/engine.js +6 -3
- package/lib/global-graph.js +282 -0
- package/lib/graph.js +190 -14
- package/lib/inbound.js +19 -0
- package/lib/index.js +33 -1
- package/lib/inject.js +277 -17
- package/lib/lexicon.js +1115 -0
- package/lib/local-vector-service.js +8 -6
- package/lib/managed-runtime.js +33 -2
- package/lib/memory.js +585 -76
- package/lib/memu.js +2 -2
- package/lib/migrate.js +83 -2
- package/lib/private-links.js +587 -0
- package/lib/private.js +128 -7
- package/lib/prompts/global-curator.md +76 -19
- package/lib/prompts/private-consolidation.coding.md +4 -1
- package/lib/prompts/private-consolidation.md +3 -1
- package/lib/prompts/private-consolidation.mixed.md +3 -1
- package/lib/prompts/private-consolidation.rp.md +3 -1
- package/lib/prompts.js +1 -1
- package/lib/rpc.js +622 -13
- package/lib/state.js +4 -1
- package/lib/text-retrieval.js +661 -0
- package/lib/text-similarity.js +124 -0
- package/lib/tools.js +230 -16
- package/lib/vector-migration.js +28 -3
- package/lib/vector-profile.js +24 -0
- package/lib/webui/standalone.css +17 -0
- package/lib/webui/standalone.js +2 -0
- package/package.json +3 -2
- package/scripts/acceptance-local.mjs +8 -5
- package/scripts/curator-pair-calibrate.mjs +259 -0
- package/scripts/lexicon-calibrate.mjs +230 -0
- package/scripts/lexicon-dedupe.mjs +318 -0
- package/scripts/replay.mjs +573 -0
- package/tests/absorb-review.test.mjs +353 -0
- package/tests/appendix-b.test.mjs +6 -2
- package/tests/appendix-b2.test.mjs +2 -2
- package/tests/client-export.test.mjs +520 -0
- package/tests/client-render.test.mjs +19 -3
- package/tests/consolidation-credential.test.mjs +16 -5
- package/tests/consolidation-feed.test.mjs +96 -0
- package/tests/consolidation-fork.test.mjs +144 -10
- package/tests/consolidation-snapshot.test.mjs +82 -4
- package/tests/curator-absorb.test.mjs +443 -0
- package/tests/curator-calibrate.test.mjs +173 -0
- package/tests/curator-clusters.test.mjs +281 -0
- package/tests/curator-commit.test.mjs +324 -0
- package/tests/curator-evidence.test.mjs +102 -0
- package/tests/curator-link.test.mjs +316 -0
- package/tests/curator-pairing.test.mjs +252 -0
- package/tests/curator-probe.test.mjs +15 -6
- package/tests/curator-review-mode.test.mjs +314 -0
- package/tests/disclosure.test.mjs +2 -1
- package/tests/fixtures/curator-pairs/labeled.v1.jsonl +90 -0
- package/tests/fixtures/lexicon-stub-hooks.mjs +15 -0
- package/tests/fixtures/lexicon-stub.mjs +284 -0
- package/tests/graph-cascade.test.mjs +223 -0
- package/tests/graph.test.mjs +113 -0
- package/tests/help-page.test.mjs +415 -0
- package/tests/hybrid-recall.test.mjs +32 -2
- package/tests/inbound.test.mjs +6 -3
- package/tests/inject-guide.test.mjs +28 -0
- package/tests/inject.test.mjs +157 -5
- package/tests/lexicon-calibrate.test.mjs +48 -0
- package/tests/lexicon-dedupe.test.mjs +171 -0
- package/tests/lexicon-frequency.test.mjs +179 -0
- package/tests/lexicon-inject.test.mjs +410 -0
- package/tests/lexicon-perf.test.mjs +436 -0
- package/tests/lexicon-ui.test.mjs +547 -0
- package/tests/lexicon.test.mjs +922 -0
- package/tests/managed-memory.test.mjs +55 -0
- package/tests/managed-runtime.test.mjs +32 -0
- package/tests/private-links.test.mjs +445 -0
- package/tests/prompts.test.mjs +35 -0
- package/tests/recall-dedup.test.mjs +446 -0
- package/tests/sidebar-beat.test.mjs +5 -1
- package/tests/tool-schema.test.mjs +1 -1
- package/tests/tools.test.mjs +112 -3
- package/tests/vector-migration.test.mjs +58 -1
- package/tests/webui-auth.test.mjs +348 -2
- package/tests/webui.test.mjs +191 -2
|
@@ -89,17 +89,19 @@ function profileFor(catalogId) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function installationFor(id, sharedRuntime = null) {
|
|
92
|
-
const status = getDownloader().getStatus(id, { deep:
|
|
92
|
+
const status = getDownloader().getStatus(id, { deep: true })
|
|
93
93
|
// 所有可用模型 pin 的是同一个受管 runtime;每个模型各走一遍运行时目录树(几百个文件)
|
|
94
94
|
// 会让每次 getState 多花几百毫秒。上层已经算过一次就复用。
|
|
95
95
|
const runtime = sharedRuntime || localVectorRuntimeStatus({ modelId: id })
|
|
96
|
+
const degraded = status.state === 'installed' && status.verified === false
|
|
96
97
|
return {
|
|
97
|
-
status: status.state,
|
|
98
|
-
installed: status.installed === true,
|
|
99
|
-
|
|
98
|
+
status: degraded ? 'degraded' : status.state,
|
|
99
|
+
installed: status.installed === true && !degraded,
|
|
100
|
+
verified: status.verified ?? null,
|
|
101
|
+
modelDir: status.installed && !degraded ? path.join(root, id) : null,
|
|
100
102
|
runtimeDir: runtime.ready ? runtime.path : null,
|
|
101
103
|
fingerprintMatches: status.fingerprintMatches ?? null,
|
|
102
|
-
error: status.error || null,
|
|
104
|
+
error: degraded ? { code: 'EMBEDDING_INSTALL_TAMPERED', message: 'installed embedding files failed deep verification' } : (status.error || null),
|
|
103
105
|
progress: status.progress || null,
|
|
104
106
|
}
|
|
105
107
|
}
|
|
@@ -164,7 +166,7 @@ export function getLocalVectorState() {
|
|
|
164
166
|
|
|
165
167
|
export function selectLocalVectorModel(id) {
|
|
166
168
|
const status = getDownloader().getStatus(String(id), { deep: true })
|
|
167
|
-
if (status.state !== 'installed' || status.fingerprintMatches === false) {
|
|
169
|
+
if (status.state !== 'installed' || status.verified !== true || status.fingerprintMatches === false) {
|
|
168
170
|
const error = new Error('install and verify the local embedding model before selecting it')
|
|
169
171
|
error.code = 'LOCAL_VECTOR_MODEL_NOT_INSTALLED'
|
|
170
172
|
throw error
|
package/lib/managed-runtime.js
CHANGED
|
@@ -20,6 +20,28 @@ export function verifyRuntimeArchive(data, digest) {
|
|
|
20
20
|
if (crypto.createHash('sha256').update(data).digest('hex') !== digest) throw new Error('managed runtime checksum mismatch; refusing to execute')
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
function executableFingerprint(file) {
|
|
24
|
+
try {
|
|
25
|
+
const stat = fs.lstatSync(file)
|
|
26
|
+
if (!stat.isFile() || stat.isSymbolicLink()) return null
|
|
27
|
+
const sha256 = crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex')
|
|
28
|
+
return { bytes: stat.size, sha256 }
|
|
29
|
+
} catch {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function verifiedRuntimeMetadata(file, asset) {
|
|
35
|
+
try {
|
|
36
|
+
const metadata = JSON.parse(fs.readFileSync(file, 'utf8'))
|
|
37
|
+
return metadata && metadata.version === UV_VERSION && metadata.archive === asset[0] && metadata.archiveSha256 === asset[1] && Number.isInteger(metadata.executableBytes) && typeof metadata.executableSha256 === 'string'
|
|
38
|
+
? metadata
|
|
39
|
+
: null
|
|
40
|
+
} catch {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
23
45
|
export async function ensureManagedPython({ run, log = () => {}, fetcher = fetch } = {}) {
|
|
24
46
|
const platform = `${process.platform}-${process.arch}`
|
|
25
47
|
const asset = ASSETS[platform]
|
|
@@ -33,7 +55,14 @@ export async function ensureManagedPython({ run, log = () => {}, fetcher = fetch
|
|
|
33
55
|
UV_PYTHON_BIN_DIR: ensureDir(path.join(root, 'bin')),
|
|
34
56
|
UV_NO_PROGRESS: '1', UV_PYTHON_PREFERENCE: 'only-managed', UV_NO_MODIFY_PATH: '1', UV_NO_CONFIG: '1',
|
|
35
57
|
}
|
|
36
|
-
|
|
58
|
+
const metadataFile = path.join(bin, 'verified.json')
|
|
59
|
+
const metadata = verifiedRuntimeMetadata(metadataFile, asset)
|
|
60
|
+
const fingerprint = executableFingerprint(executable)
|
|
61
|
+
const reusable = Boolean(metadata && fingerprint && metadata.executableBytes === fingerprint.bytes && metadata.executableSha256 === fingerprint.sha256)
|
|
62
|
+
if (!reusable) {
|
|
63
|
+
if (fingerprint || fs.existsSync(executable)) log(`managed uv ${UV_VERSION} is missing trusted metadata or was modified; replacing it`)
|
|
64
|
+
try { fs.rmSync(executable, { force: true }) } catch {}
|
|
65
|
+
try { fs.rmSync(metadataFile, { force: true }) } catch {}
|
|
37
66
|
log(`no usable Python with pip; downloading pinned uv ${UV_VERSION}`)
|
|
38
67
|
const response = await fetcher(`https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/${asset[0]}`, { signal: AbortSignal.timeout(120_000) })
|
|
39
68
|
if (!response.ok || Number(response.headers.get('content-length')) > 64 * 1024 * 1024) throw new Error('managed runtime download failed or is too large')
|
|
@@ -63,7 +92,9 @@ export async function ensureManagedPython({ run, log = () => {}, fetcher = fetch
|
|
|
63
92
|
}
|
|
64
93
|
if (fs.existsSync(temporary)) fs.renameSync(temporary, executable)
|
|
65
94
|
if (process.platform !== 'win32') fs.chmodSync(executable, 0o700)
|
|
66
|
-
|
|
95
|
+
const installedFingerprint = executableFingerprint(executable)
|
|
96
|
+
if (!installedFingerprint) throw new Error('managed runtime executable is not a regular file')
|
|
97
|
+
writeJson(metadataFile, { version: UV_VERSION, archive: asset[0], archiveSha256: asset[1], executableBytes: installedFingerprint.bytes, executableSha256: installedFingerprint.sha256 })
|
|
67
98
|
}
|
|
68
99
|
const version = await run(executable, ['--version'], { env, timeoutMs: 20_000 })
|
|
69
100
|
if (version.code !== 0 || !version.stdout.startsWith(`uv ${UV_VERSION} `) && version.stdout.trim() !== `uv ${UV_VERSION}`) throw new Error('managed uv version mismatch')
|