@a9i5k4/dsh-auto-memory 2.1.7 → 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 +17 -2
- package/lib/index.js +2 -1
- package/lib/python-setup.js +23 -8
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -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
|
@@ -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')
|
|
@@ -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 装 transformers+onnxruntime
|
|
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": {
|