@a9i5k4/dsh-auto-memory 2.1.6 → 2.1.8
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/lib/client.js +19 -4
- package/lib/index.js +2 -1
- package/lib/python-setup.js +25 -10
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -147,7 +147,7 @@ window.__ModuleLoader__.load({
|
|
|
147
147
|
storageScanHint: '语料健康 = 逐源比对索引(sidecar)与正文的 digest。手动改动记忆文件后索引会失配,该记忆会退出检索直到重建索引。',
|
|
148
148
|
storageDeleteHint: '删除记忆 = 正文原子删除 + 在途唤起包清理 + 派生事实撤销(三联动)。已产生的 seen 证据不改写。',
|
|
149
149
|
secSemantic: '自动记忆引擎', semMode: '检索模式', semAuto: '自动(推荐)', semLexOnly: '仅词法', semJs: '内置语义', semPy: '高级 Python',
|
|
150
|
-
pyWizTitle: 'Python 引擎一键安装', pyWizStep1: '① 检测 Python 环境', pyWizStep2: '② 创建独立虚拟环境(~/.dsh/python-engine/.venv,不污染系统)', pyWizStep3: '③ 安装引擎依赖(
|
|
150
|
+
pyWizTitle: 'Python 引擎一键安装', pyWizStep1: '① 检测 Python 环境', pyWizStep2: '② 创建独立虚拟环境(~/.dsh/python-engine/.venv,不污染系统)', pyWizStep3: '③ 安装引擎依赖(transformers + onnxruntime + torch)', pyWizStep4: '④ 下载 BGE-M3 int8 模型(~539MB,断点续传,失败自动换源)',
|
|
151
151
|
pyWizDetect: '开始检测', pyWizRedetect: '重新检测', pyWizCreate: '创建虚拟环境', pyWizInstall: '安装依赖', pyWizDownload: '开始下载', pyWizCancel: '取消下载', pyWizDone: '全部就绪 ✓ — 回上方启用即可', pyWizOk: 'ok', pyWizMissing: '未找到', pyWizTooOld: '版本不兼容(需 3.9-3.12)', pyWizVenvRec: '推荐', pyWizEta: '剩余', pyWizSec: '秒', pyWizModelHint: '模型与虚拟环境安装在 ~/.dsh/python-engine/(用户目录),升级/重装插件不受影响。',
|
|
152
152
|
semModeHint: '自动=内置语义就绪即用,否则词法保底;高级 Python 需另行安装。',
|
|
153
153
|
fAssocEngine: '启用自动记忆引擎', fAssocEngineHint: '总开关。开启后自动观测上下文、语义检索并适时唤起记忆注入(消费少量 token)。关闭则整个引擎不运行——不检索、不判定、不注入、不生成唤起记录。介意 token 消耗或担心动作跑偏的用户可关闭。默认关。',
|
|
@@ -286,7 +286,7 @@ window.__ModuleLoader__.load({
|
|
|
286
286
|
storageScanHint: 'Corpus health = compare each source\'s index (sidecar) against its body digest. After you hand-edit a memory file the index no longer matches, and that memory drops out of retrieval until the index is rebuilt.',
|
|
287
287
|
storageDeleteHint: 'Delete = atomic body removal + in-flight activation purge + derived-fact revocation (cascading). Evidence already recorded (seen) is never rewritten.',
|
|
288
288
|
secSemantic: 'Semantic engine', semMode: 'Retrieval mode', semAuto: 'Auto (recommended)', semLexOnly: 'Lexical only', semJs: 'Built-in semantic', semPy: 'Advanced Python',
|
|
289
|
-
pyWizTitle: 'One-click Python engine setup', pyWizStep1: '1. Detect Python environment', pyWizStep2: '2. Create isolated venv (~/.dsh/python-engine/.venv, system untouched)', pyWizStep3: '3. Install engine deps (
|
|
289
|
+
pyWizTitle: 'One-click Python engine setup', pyWizStep1: '1. Detect Python environment', pyWizStep2: '2. Create isolated venv (~/.dsh/python-engine/.venv, system untouched)', pyWizStep3: '3. Install engine deps (transformers + onnxruntime + torch)', pyWizStep4: '4. Download BGE-M3 int8 model (~539MB, resumable, auto mirror failover)',
|
|
290
290
|
pyWizDetect: 'Detect', pyWizRedetect: 'Re-detect', pyWizCreate: 'Create venv', pyWizInstall: 'Install deps', pyWizDownload: 'Start download', pyWizCancel: 'Cancel download', pyWizDone: 'All ready - enable it above', pyWizOk: 'ok', pyWizMissing: 'not found', pyWizTooOld: 'incompatible (need 3.9-3.12)', pyWizVenvRec: 'recommended', pyWizEta: 'eta', pyWizSec: 's', pyWizModelHint: 'Model and venv live in ~/.dsh/python-engine/ (user dir) - plugin upgrades never touch them.',
|
|
291
291
|
fAssocEngine: 'Enable automatic memory engine', fAssocEngineHint: 'Master switch. On = auto-observe context, semantic retrieval, and timely memory-activation injection (costs a little token). Off = the whole engine stops — no retrieval, no decide, no injection, no activation records. For users concerned about token cost or off-course actions. Default off.',
|
|
292
292
|
secMemoryHubHint: 'Memory Hub = the orchestrator for three memory layers (episodic / semantic / procedural). When on, it distills episodes from dialogue, solidifies facts, and turns repeatedly-successful workflows into skills that are auto-recalled in similar contexts.',
|
|
@@ -1223,6 +1223,17 @@ window.__ModuleLoader__.load({
|
|
|
1223
1223
|
var pollPair = useState(null)
|
|
1224
1224
|
var poll = pollPair[0]
|
|
1225
1225
|
var setPoll = pollPair[1]
|
|
1226
|
+
var gpuPair = useState(function () { try { return localStorage.getItem('dsh-auto-memory.pyGpu') === '1' } catch (eG) { return false } })
|
|
1227
|
+
var gpuPref = gpuPair[0]
|
|
1228
|
+
var setGpuPref = function (v) {
|
|
1229
|
+
gpuPair[1](v)
|
|
1230
|
+
try { localStorage.setItem('dsh-auto-memory.pyGpu', v ? '1' : '0') } catch (eG) {}
|
|
1231
|
+
}
|
|
1232
|
+
var actGpu = function () {
|
|
1233
|
+
if (busy) return
|
|
1234
|
+
setBusy(true)
|
|
1235
|
+
apiPost(API.pyDeps, { gpu: gpuPref }).then(function (d) { setData(d); setBusy(false); setPoll(true); var ph = d && d.phase; if (ph === 'ready' || ph === 'error' || ph === 'idle') setPoll(false) }).catch(function () { setBusy(false); setPoll(false) })
|
|
1236
|
+
}
|
|
1226
1237
|
var refresh = function () { apiGet(API.pyStatus).then(function (d) { if (d) setData(d) }).catch(function () {}) }
|
|
1227
1238
|
useEffect(function () {
|
|
1228
1239
|
var alive = true
|
|
@@ -1267,7 +1278,11 @@ window.__ModuleLoader__.load({
|
|
|
1267
1278
|
stepRow(t('pyWizStep2'), data.venvOk ? true : 'run',
|
|
1268
1279
|
(!data.venvOk && (data.pythons || []).some(function (p2) { return p2.status === 'ok' && !p2.isVenv })) ? h('button', Object.assign({}, btnCls, { onClick: function () { act(API.pyVenv, true) } }), t('pyWizCreate')) : null),
|
|
1269
1280
|
stepRow(t('pyWizStep3'), data.depsOk ? true : 'run',
|
|
1270
|
-
(data.venvOk && !data.depsOk) ? h('
|
|
1281
|
+
(data.venvOk && !data.depsOk) ? h('span', { style: { display: 'flex', gap: '8px', alignItems: 'center' } },
|
|
1282
|
+
h('label', { style: { display: 'flex', gap: '4px', alignItems: 'center', fontSize: 'calc(10.5px * var(--dam-scale))' } },
|
|
1283
|
+
h('input', { type: 'checkbox', checked: gpuPref, onChange: function (e) { setGpuPref(e.target.checked) } }),
|
|
1284
|
+
locale === 'zh' ? 'GPU 推理(NVIDIA,需已装 CUDA;否则自动回退 CPU)' : 'GPU inference (NVIDIA + CUDA; auto-falls back to CPU)'),
|
|
1285
|
+
h('button', Object.assign({}, btnCls, { onClick: function () { actGpu() } }), t('pyWizInstall'))) : null),
|
|
1271
1286
|
stepRow(t('pyWizStep4'), data.modelReady ? true : 'run',
|
|
1272
1287
|
(!data.modelReady && !dlActive) ? h('button', Object.assign({}, btnCls, { onClick: function () { act(API.pyModel, true) } }), t('pyWizDownload')) : null,
|
|
1273
1288
|
dlActive ? h('button', { 'data-dam-btn': '', onClick: function () { apiPost(API.pyCancel, {}).then(refresh).catch(function () {}) } }, t('pyWizCancel')) : null),
|
|
@@ -3421,7 +3436,7 @@ window.__ModuleLoader__.load({
|
|
|
3421
3436
|
h('option', { value: 'auto' }, t('mAuto')),
|
|
3422
3437
|
h('option', { value: 'cn' }, t('mCn')),
|
|
3423
3438
|
h('option', { value: 'intl' }, t('mIntl'))) : null,
|
|
3424
|
-
ready ? h('button', { 'data-dam-btn': '', onClick: function () { setGuide(''); var n2 = Object.assign({}, cfg); n2.semanticEngineMode = guide; if (guide === 'js') { n2.activationSource = 'js'; n2.contextSinkMode = 'null' } else if (guide === 'python') { n2.activationSource = 'python'; n2.contextSinkMode = 'python' } setCfg(n2); setDirty(true) } }, locale === 'zh' ? '启用并继续' : 'Enable & continue') : null,
|
|
3439
|
+
ready ? h('button', { 'data-dam-btn': '', onClick: function () { setGuide(''); var n2 = Object.assign({}, cfg); n2.semanticEngineMode = guide; if (guide === 'js') { n2.activationSource = 'js'; n2.contextSinkMode = 'null' } else if (guide === 'python') { n2.activationSource = 'python'; n2.contextSinkMode = 'python'; try { var gp = localStorage.getItem('dsh-auto-memory.pyGpu'); if (gp === '1') n2.pythonGpu = true } catch (eL) {} } setCfg(n2); setDirty(true) } }, locale === 'zh' ? '启用并继续' : 'Enable & continue') : null,
|
|
3425
3440
|
!ready && isJs && !dlActive ? h('button', { 'data-dam-btn': '', onClick: startDl }, (dl.phase === 'error' || dl.phase === 'cancelled') ? t('semDlRetry') : t('semDlStart')) : null,
|
|
3426
3441
|
!ready && isJs && dlActive ? h('button', { 'data-dam-btn': '', onClick: cancelDl }, t('semDlCancel')) : null,
|
|
3427
3442
|
h('button', { 'data-dam-btn': '', onClick: function () { setGuide('') } }, t('gotIt'))))
|
package/lib/index.js
CHANGED
|
@@ -5458,7 +5458,8 @@ export function apply(ctx, config) {
|
|
|
5458
5458
|
handler: async (req, res) => {
|
|
5459
5459
|
if (!isLoopbackRequest(req)) return writeJson(res, 403, { error: 'forbidden: loopback-only' })
|
|
5460
5460
|
if ((req.method || 'POST') !== 'POST') return writeJson(res, 405, { error: 'method not allowed' })
|
|
5461
|
-
|
|
5461
|
+
const body = await readJsonBody(req).catch(() => ({}))
|
|
5462
|
+
try { writeJson(res, 200, await engine._pythonSetup.ensureDeps({ gpu: !!(body && body.gpu) })) } catch (e) { writeJson(res, 500, { error: String(e && e.message || e) }) }
|
|
5462
5463
|
},
|
|
5463
5464
|
},
|
|
5464
5465
|
{
|
package/lib/python-setup.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 四步链路(全部走本模块,UI 只管展示状态与点击):
|
|
5
5
|
* ①detect — 探测系统 Python(≥3.9)/既有 venv/模型本体;全部只读。
|
|
6
6
|
* ②venv — python -m venv <userDir>/python-engine/.venv(幂等:已存在直接跳过)。
|
|
7
|
-
* ③deps — venv 内 pip 安装运行依赖(
|
|
7
|
+
* ③deps — venv 内 pip 安装运行依赖(transformers/onnxruntime/torch,清华镜像兜底)。
|
|
8
8
|
* ④model — BGE-M3 int8(~539MB)下载到 <userDir>/python-engine/models/,
|
|
9
9
|
* cn(hf-mirror)/intl(hf 官方)双通道+SHA256 校验,复用 JS 档下载器的状态机形态。
|
|
10
10
|
*
|
|
@@ -35,8 +35,9 @@ const MODEL_SPEC = {
|
|
|
35
35
|
],
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/** venv 内 pip
|
|
39
|
-
const
|
|
38
|
+
/** venv 内 pip 依赖:#19 实测(int8 档 encode_ids 全程 numpy+onnxruntime,tokenizer 走 Rust 快速路径)——基础集无 torch,venv 体积 ~400MB。GPU 推理开关追加 onnxruntime-gpu(CUDAExecutionProvider)。池化/精度契约冻结自 R@5 0.925 基线,fastembed 注册表无 BGE-M3 且池化契约不同,不可用。 */
|
|
39
|
+
const PIP_DEPS_CPU = ['transformers', 'onnxruntime']
|
|
40
|
+
const PIP_DEPS_GPU_EXTRA = ['onnxruntime-gpu']
|
|
40
41
|
|
|
41
42
|
export function createPythonSetupPre(opts = {}) {
|
|
42
43
|
const dshHomeOf = typeof opts.dshHome === 'function' ? opts.dshHome : () => opts.dshHome || path.join(homedir(), '.dsh')
|
|
@@ -99,7 +100,7 @@ export function createPythonSetupPre(opts = {}) {
|
|
|
99
100
|
}
|
|
100
101
|
// 既有成果快照
|
|
101
102
|
st.venvOk = existsSync(venvPython())
|
|
102
|
-
st.depsOk = st.venvOk ? (await probe(venvPython(), ['-c', 'import
|
|
103
|
+
st.depsOk = st.venvOk ? (await probe(venvPython(), ['-c', 'import transformers, onnxruntime, torch; print("deps-ok")'])).ok : false
|
|
103
104
|
st.modelReady = existsSync(modelPath())
|
|
104
105
|
st.pythons = out
|
|
105
106
|
st.phase = 'idle'
|
|
@@ -110,7 +111,7 @@ export function createPythonSetupPre(opts = {}) {
|
|
|
110
111
|
return {
|
|
111
112
|
phase: st.phase, error: st.error,
|
|
112
113
|
pythons: st.pythons, chosenPython: st.chosenPython,
|
|
113
|
-
venvOk: st.venvOk, depsOk: st.depsOk, modelReady: st.modelReady,
|
|
114
|
+
venvOk: st.venvOk, depsOk: st.depsOk, modelReady: st.modelReady, wantGpu: !!st.wantGpu,
|
|
114
115
|
modelPath: modelPath(), venvPython: venvPython(),
|
|
115
116
|
modelBytes: st.modelReady ? statSync(modelPath()).size : 0, modelExpectedBytes: MODEL_SPEC.bytes,
|
|
116
117
|
dl: { ...st.dl },
|
|
@@ -136,14 +137,17 @@ export function createPythonSetupPre(opts = {}) {
|
|
|
136
137
|
return snapshot()
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
/** ③deps:venv 内 pip 装
|
|
140
|
-
async function ensureDeps() {
|
|
140
|
+
/** ③deps:venv 内 pip 装 transformers+onnxruntime(CPU 基础集);opts.gpu=true 追加 onnxruntime-gpu(用户选 GPU 推理时)。官方源失败切清华镜像。 */
|
|
141
|
+
async function ensureDeps(opts2) {
|
|
142
|
+
const wantGpu = !!(opts2 && opts2.gpu)
|
|
141
143
|
if (!st.venvOk) { st.error = 'venv 未就绪,先执行 venv 步骤'; st.phase = 'error'; return snapshot() }
|
|
142
144
|
st.phase = 'deps'
|
|
145
|
+
st.wantGpu = wantGpu
|
|
146
|
+
const deps = PIP_DEPS_CPU.concat(wantGpu ? PIP_DEPS_GPU_EXTRA : [])
|
|
143
147
|
const runPip = async (extra) => {
|
|
144
148
|
try {
|
|
145
|
-
const r = await execFileP(venvPython(), ['-m', 'pip', 'install', '--quiet'].concat(
|
|
146
|
-
{ timeout:
|
|
149
|
+
const r = await execFileP(venvPython(), ['-m', 'pip', 'install', '--quiet'].concat(deps).concat(extra || []),
|
|
150
|
+
{ timeout: 900000, windowsHide: true, maxBuffer: 4 * 1024 * 1024 })
|
|
147
151
|
return { ok: true }
|
|
148
152
|
} catch (e) { return { ok: false, tail: String((e && (e.stderr || e.message)) || e).slice(-300) } }
|
|
149
153
|
}
|
|
@@ -151,7 +155,18 @@ export function createPythonSetupPre(opts = {}) {
|
|
|
151
155
|
if (!r.ok) r = await runPip(['-i', 'https://pypi.tuna.tsinghua.edu.cn/simple'])
|
|
152
156
|
st.depsOk = !!r.ok
|
|
153
157
|
if (!r.ok) { st.error = '依赖安装失败: ' + (r.tail || ''); st.phase = 'error'; return snapshot() }
|
|
154
|
-
|
|
158
|
+
// GPU 偏好写入 embedding-config.json(worker 读 config['gpu'] 选 CUDA/CPU provider;read-modify-write 不覆盖既有键)
|
|
159
|
+
try {
|
|
160
|
+
const cfgDir = path.join(dshHomeOf(), 'memory', 'semantic')
|
|
161
|
+
mkdirSync(cfgDir, { recursive: true })
|
|
162
|
+
const cfgPath = path.join(cfgDir, 'embedding-config.json')
|
|
163
|
+
let cfg = {}
|
|
164
|
+
try { cfg = JSON.parse(await readFile(cfgPath, 'utf8')) } catch (_) {}
|
|
165
|
+
if (!cfg || typeof cfg !== 'object') cfg = {}
|
|
166
|
+
cfg.gpu = wantGpu
|
|
167
|
+
await writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf8')
|
|
168
|
+
} catch (eCfg) { diagOf('python-setup: gpu pref write failed: ' + String(eCfg && eCfg.message || eCfg)) }
|
|
169
|
+
diagOf('python-setup: deps installed into venv (gpu=' + wantGpu + ')')
|
|
155
170
|
return snapshot()
|
|
156
171
|
}
|
|
157
172
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a9i5k4/dsh-auto-memory",
|
|
3
3
|
"description": "Proactive associative memory for DSH: zero-prompt recall injected before the model speaks, three-layer auto-consolidation, skill crystallization, and Astra-style context management - handoff ledgers, PLAN whiteboard, water-level sensing. Local-first, model-agnostic, zero deps. 主动联想记忆+Astra 式上下文管理:自动唤回/自动沉淀/技能固化/交接账本与白板跨窗口续命/水位感知。",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|