dsh-layered-memory 0.8.7 → 0.8.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/README.en.md +27 -4
- package/README.md +27 -4
- package/dist/client.js +3016 -3293
- package/dist/config.d.ts +50 -4
- package/dist/config.js +8 -0
- package/dist/contract.d.ts +615 -0
- package/dist/contract.js +1 -0
- package/dist/hooks/recall.d.ts +2 -18
- package/dist/index.d.ts +40 -4
- package/dist/index.js +6 -3
- package/dist/llm-usage.d.ts +2 -1
- package/dist/llm.d.ts +30 -4
- package/dist/llm.js +76 -9
- package/dist/pipeline/rebuild.d.ts +2 -21
- package/dist/pipeline/runner.d.ts +3 -3
- package/dist/pipeline/runner.js +38 -10
- package/dist/settings.d.ts +18 -29
- package/dist/settings.js +81 -1
- package/dist/stats.d.ts +2 -26
- package/dist/stats.js +80 -21
- package/dist/store/cost-ledger.d.ts +78 -0
- package/dist/store/cost-ledger.js +173 -0
- package/dist/store/download-queue.d.ts +2 -20
- package/dist/store/embedding-source.d.ts +2 -52
- package/dist/store/runtime-installer.d.ts +2 -13
- package/dist/store/sqlite.d.ts +11 -61
- package/dist/store/sqlite.js +15 -150
- package/dist/token-cost.d.ts +3 -72
- package/package.json +8 -4
package/README.en.md
CHANGED
|
@@ -230,8 +230,8 @@ the bundle layer appends and causes `duplicate loader entry id` startup failure)
|
|
|
230
230
|
config: # keys replace whole lines (no deep merge); write out all keys you want to keep
|
|
231
231
|
family: auto # default mode for new sessions: auto | chat | work
|
|
232
232
|
llm: # static distillation route (both fields set = deployment pin,
|
|
233
|
-
provider: '' # which outranks the settings-page
|
|
234
|
-
model: '' # follows the
|
|
233
|
+
provider: '' # which outranks the settings-page route chain; when empty the route
|
|
234
|
+
model: '' # follows the route-chain primary row in the settings page or the default model)
|
|
235
235
|
```
|
|
236
236
|
|
|
237
237
|
| Field | Default | Description |
|
|
@@ -272,9 +272,10 @@ the bundle layer appends and causes `duplicate loader entry id` startup failure)
|
|
|
272
272
|
| `embedding.allowLocalModels` | `true` | Allow the local embedding tier (deployment ceiling; when off, no model downloads and no local tier in settings) |
|
|
273
273
|
| `embedding.mirror` | `https://hf-mirror.com` | Download mirror root for local models (can be changed back to `https://huggingface.co`) |
|
|
274
274
|
| `embedding.proxy` | `''` | Three-state download proxy: `''` (default) = auto-detect proxy env vars (`HTTPS_PROXY`/`ALL_PROXY` etc., honoring `NO_PROXY`); `none` = disable, always direct; any other value = proxy URL (e.g. `http://127.0.0.1:7890`). Direct connections to the mirror are intermittently unreachable on some networks (connect timeouts and poisoned bytes have both been observed) — keep the default auto-detection on machines with a proxy |
|
|
275
|
-
| `llm.provider/model` | empty | Static distillation route (deployment pin): when **both** fields are set the route is locked, outranking the settings-page
|
|
275
|
+
| `llm.provider/model` | empty | Static distillation route (deployment pin): when **both** fields are set the route is locked, outranking the settings-page runtime route chain and the default model (deployments can force distillation onto a specific route); when empty the route follows "settings-page route-chain primary → default model". At runtime, configure the primary route and fallback chain in the **route-chain editor** under Settings → Memory → Overview → distillation parameters (pick from **configured providers**, including custom ones added in dsh Settings → Models; the primary row may stay empty to follow the default model) — a non-empty chain takes over this static config wholesale, effective immediately with no restart |
|
|
276
|
+
| `llm.fallbacks` | `[]` | Distillation fallback chain: an ordered list of backup routes tried one by one when the primary route fails (error / cut-off / network error / **empty output**); each entry is `{provider, model, reasoningEffort?}` (a non-empty effort overrides the global `llm.reasoningEffort`, still clamped by model capability); entries identical to the primary route are skipped; **each route gets the full `timeoutMs`**; when all routes fail, the existing per-session backoff takes over. Empty list (default) = single-route behavior unchanged (see [Distillation fallback chain & slow-TTFT models](#distillation-fallback-chain--slow-ttft-models) below); a non-empty settings-page runtime chain (`distillChain`) takes over **both** the primary route and the fallback chain (a single-row chain = explicitly no fallbacks), empty = follow this config |
|
|
276
277
|
| `llm.maxTokens` | `65536` | Fallback output cap for non-layered calls. Each distillation stage has its own budget (extraction 16k / dedup 8k / L2 32k / L3 16k; auto ×4 when the reasoning effort is high/xhigh/max, so thinking can't starve the text budget); the per-layer budgets are runtime-adjustable in Settings → Memory → Overview → distillation parameters (empty/0 = built-in defaults) |
|
|
277
|
-
| `llm.reasoningEffort` | empty | Distillation reasoning effort: empty = **auto** (resolved from model capability: the model's default tier, else `high`); an explicit value (`off`/`none`/`minimal`/`low`/`medium`/`high`/`xhigh`/`max`) is only sent when the model declares support — effort vocabularies differ across providers (deepseek accepts `off`, OpenAI-style APIs use `none`, models that declare no tiers get nothing), and unsupported tiers degrade to not-sending with a one-time warning; output budgets auto-×4 at high/xhigh/max.
|
|
278
|
+
| `llm.reasoningEffort` | empty | Distillation reasoning effort: empty = **auto** (resolved from model capability: the model's default tier, else `high`); an explicit value (`off`/`none`/`minimal`/`low`/`medium`/`high`/`xhigh`/`max`) is only sent when the model declares support — effort vocabularies differ across providers (deepseek accepts `off`, OpenAI-style APIs use `none`, models that declare no tiers get nothing), and unsupported tiers degrade to not-sending with a one-time warning; output budgets auto-×4 at high/xhigh/max. At runtime, override the effort **per route** in the settings-page route-chain editor (per-row dropdown; the tier list follows each model's declared capability live, defaulting to this value) |
|
|
278
279
|
| `llm.temperature` | `0.3` | Distillation temperature |
|
|
279
280
|
| `llm.maxInputChars` | `700000` | Input character budget per distillation call (over-budget L1 inputs are chunked automatically); runtime-adjustable in Settings → distillation parameters → input budget (empty/0 = follow this value) |
|
|
280
281
|
| `llm.timeoutMs` | `120000` | Per-call distillation timeout (ms) |
|
|
@@ -282,6 +283,28 @@ the bundle layer appends and causes `duplicate loader entry id` startup failure)
|
|
|
282
283
|
| `tools` | `true` | Whether to register model-callable memory tools |
|
|
283
284
|
| `benchControl` | `false` | Register the in-process bench control service (rebuild trigger / session-mode setting / distillation usage snapshot — used by the benchmark's lifecycle track). Off by default — zero surface in production deployments; do not enable casually |
|
|
284
285
|
|
|
286
|
+
### Distillation fallback chain & slow-TTFT models
|
|
287
|
+
|
|
288
|
+
Free/slow tiers of some inference providers have **first-token latencies (TTFT) upwards of 20 seconds**, while some upstream gateways cut a silent connection at ~20s — distillation calls then fail at a fixed ~20s (`llm aborted`) long before the plugin's 120s timeout could ever matter (the scenario measured in [#31](https://github.com/JunNanLYS/dsh-layered-memory/issues/31)). Three mitigations, pick as needed:
|
|
289
|
+
|
|
290
|
+
1. **Switch route** (most direct): change the primary route live in the route-chain editor under Settings → Memory → Overview → distillation parameters (or move a fast route to the head of the chain), or pin `llm.provider`/`llm.model` statically.
|
|
291
|
+
2. **Fallback chain** (automatic demotion): when the primary route fails, backup routes are tried in order with no manual intervention:
|
|
292
|
+
|
|
293
|
+
```yaml
|
|
294
|
+
llm:
|
|
295
|
+
provider: opencode-go # primary route (may be left unpinned: settings-page route-chain primary / default model)
|
|
296
|
+
model: ox-alpha-free
|
|
297
|
+
fallbacks: # entry order = demotion priority; unset = single-route behavior unchanged
|
|
298
|
+
- provider: opencode-go
|
|
299
|
+
model: deepseek-v4-flash
|
|
300
|
+
reasoningEffort: low # optional: per-route effort override (defaults to the global value)
|
|
301
|
+
- provider: deepseek-official
|
|
302
|
+
model: deepseek-v4-flash
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Failure = error / cut-off / network error / **empty output** (stream ends normally with 0 characters — worthless for distillation since parsing always fails, so it is treated as a route failure rather than an empty return); caller-initiated cancellation does not demote; each route gets the **full** `llm.timeoutMs` (a shared budget would give a slow-TTFT fallback route less time than its real first-packet needs, defeating the chain); token costs are recorded per attempt (failed attempts get a row too, with whatever tokens arrived before the stream broke), and successful calls are attributed to the route that actually served. The route chain can also be adjusted at runtime in the route-chain editor under Settings → Memory → Overview → distillation parameters (no config edit or restart needed); the YAML below suits deployments that want to pin the static chain.
|
|
306
|
+
3. **Raise the timeout**: `llm.timeoutMs` only helps when the route is genuinely slow but the gateway doesn't cut; if the gateway kills at 20s, raising the plugin timeout is futile — use the first two layers.
|
|
307
|
+
|
|
285
308
|
## Storage Layout
|
|
286
309
|
|
|
287
310
|
<p align="center">
|
package/README.md
CHANGED
|
@@ -232,8 +232,8 @@ ONNX 量化 **CPU 推理**——无需 API Key,数据不出本机)。本地
|
|
|
232
232
|
name: dsh-layered-memory
|
|
233
233
|
config: # 键按行整体替换(不深合并),按需写全要保留的键
|
|
234
234
|
family: auto # 新会话默认档:auto | chat | work
|
|
235
|
-
llm: # 蒸馏模型静态路由(双字段齐 = 部署 pin
|
|
236
|
-
provider: '' #
|
|
235
|
+
llm: # 蒸馏模型静态路由(双字段齐 = 部署 pin,优先于设置页路由链;
|
|
236
|
+
provider: '' # 留空则跟随设置页路由链主路由或当前默认模型)
|
|
237
237
|
model: ''
|
|
238
238
|
```
|
|
239
239
|
|
|
@@ -275,9 +275,10 @@ ONNX 量化 **CPU 推理**——无需 API Key,数据不出本机)。本地
|
|
|
275
275
|
| `embedding.allowLocalModels` | `true` | 允许本地嵌入档(部署上限:关闭后设置页不能下载模型、不能切本地档) |
|
|
276
276
|
| `embedding.mirror` | `https://hf-mirror.com` | 本地模型下载镜像根地址(可改回官方 `https://huggingface.co`) |
|
|
277
277
|
| `embedding.proxy` | `''` | 模型下载代理三态:`''`(默认)= 自动探测代理环境变量(`HTTPS_PROXY`/`ALL_PROXY` 等,尊重 `NO_PROXY`);`none` = 禁用强制直连;其他值 = 代理 URL(如 `http://127.0.0.1:7890`)。镜像直连在国内网络间歇不可达(直连超时与污染字节交替出现过),开代理的机器建议保持默认自动探测 |
|
|
278
|
-
| `llm.provider/model` | 空 | 蒸馏模型静态路由(部署 pin):provider 与 model
|
|
278
|
+
| `llm.provider/model` | 空 | 蒸馏模型静态路由(部署 pin):provider 与 model **双字段齐**时锁定蒸馏路由,优先于设置页的运行时路由链与默认模型(部署可强制蒸馏走指定路由);留空则跟随"设置页路由链主路由 → 默认模型"。运行时可在设置页 → 记忆 → 概览 → 蒸馏参数的**蒸馏路由链编辑器**里配置主路由与回退链(从**已配置的供应商**(含 dsh 设置 → 模型里添加的自定义供应商)中选择,主路由行可留空跟随默认模型),非空即整体接管本静态配置,即时生效无需重启 |
|
|
279
|
+
| `llm.fallbacks` | `[]` | 蒸馏回退链:主路由失败(报错/被掐断/网络异常/**空输出**)后按条目顺序逐个降级尝试的备用路由列表,条目 = `{provider, model, reasoningEffort?}`(档位非空覆盖全局 `llm.reasoningEffort`,仍按模型能力钳制);与主路由完全相同的条目自动跳过;**每条路由各享全额 `timeoutMs`**;全部失败交既有按会话退避重试。空数组(缺省)= 单路由行为不变(详见下方[蒸馏回退链与慢 TTFT 模型](#蒸馏回退链与慢-ttft-模型));设置页运行时路由链(`distillChain`)非空时**整体接管**主路由与回退链(单行链 = 显式无回退),空 = 跟随本配置 |
|
|
279
280
|
| `llm.maxTokens` | `65536` | 未分层调用的兜底输出总闸。各蒸馏层有独立预算(抽取 16k / 去重 8k / L2 32k / L3 16k;思考档 high/xhigh/max 时自动 ×4,防 reasoning 吃光预算),分层预算可在设置页 → 记忆 → 概览 → 蒸馏参数运行时调整(留空/0 = 跟随内置默认) |
|
|
280
|
-
| `llm.reasoningEffort` | 空 | 蒸馏思考档位:空串 = **自动**(按模型能力解析:模型默认档 → `high`);显式值(`off`/`none`/`minimal`/`low`/`medium`/`high`/`xhigh`/`max`)仅在该模型声明支持时发送——跨供应商 effort 词汇表不同(deepseek 认 `off`,OpenAI 系是 `none`,未声明档位的模型不传),不支持的档位自动降级为不传并告警一次;思考档 high/xhigh/max 时输出预算自动 ×4
|
|
281
|
+
| `llm.reasoningEffort` | 空 | 蒸馏思考档位:空串 = **自动**(按模型能力解析:模型默认档 → `high`);显式值(`off`/`none`/`minimal`/`low`/`medium`/`high`/`xhigh`/`max`)仅在该模型声明支持时发送——跨供应商 effort 词汇表不同(deepseek 认 `off`,OpenAI 系是 `none`,未声明档位的模型不传),不支持的档位自动降级为不传并告警一次;思考档 high/xhigh/max 时输出预算自动 ×4。运行时可在设置页路由链编辑器里**逐路由**覆盖档位(行内下拉,词表按各模型声明的能力实时显示,缺省跟随本值) |
|
|
281
282
|
| `llm.temperature` | `0.3` | 蒸馏温度 |
|
|
282
283
|
| `llm.maxInputChars` | `700000` | 单次蒸馏输入字符预算(超限的 L1 输入自动分块抽取);运行时可在设置页 → 蒸馏参数 → 输入预算调整(留空/0 = 跟随本值) |
|
|
283
284
|
| `llm.timeoutMs` | `120000` | 单次蒸馏调用超时(ms) |
|
|
@@ -285,6 +286,28 @@ ONNX 量化 **CPU 推理**——无需 API Key,数据不出本机)。本地
|
|
|
285
286
|
| `tools` | `true` | 是否注册模型可调用的记忆工具 |
|
|
286
287
|
| `benchControl` | `false` | 注册 bench 控制服务(进程内 rebuild 触发/会话档位设置/蒸馏用量快照,供基准 lifecycle 赛道)。默认关——生产部署零表面积,勿随意开启 |
|
|
287
288
|
|
|
289
|
+
### 蒸馏回退链与慢 TTFT 模型
|
|
290
|
+
|
|
291
|
+
部分推理供应商的免费/慢速档位**首 token 延迟(TTFT)可达 20 秒以上**,而部分上游网关会在连接静默约 20 秒时掐断——蒸馏调用以固定 ~20s 失败(`llm aborted`),插件侧 120s 超时根本轮不到生效([#31](https://github.com/JunNanLYS/dsh-layered-memory/issues/31) 的实测场景)。三层缓解按需取用:
|
|
292
|
+
|
|
293
|
+
1. **换路由**(最直接):设置页 → 记忆 → 概览 → 蒸馏参数的路由链编辑器即时改主路由(或把快路由排到链首),或静态 pin `llm.provider`/`llm.model`。
|
|
294
|
+
2. **回退链**(自动降级):主路由失败时按序自动换备用路由,无需人工干预:
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
llm:
|
|
298
|
+
provider: opencode-go # 主路由(也可不 pin,跟随设置页路由链主路由/默认模型)
|
|
299
|
+
model: ox-alpha-free
|
|
300
|
+
fallbacks: # 条目顺序 = 降级优先级;不配置 = 单路由行为不变
|
|
301
|
+
- provider: opencode-go
|
|
302
|
+
model: deepseek-v4-flash
|
|
303
|
+
reasoningEffort: low # 可选:该路由的档位覆盖(缺省跟随全局)
|
|
304
|
+
- provider: deepseek-official
|
|
305
|
+
model: deepseek-v4-flash
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
失败 = 报错 / 被掐断 / 网络异常 / **空输出**(流正常结束但 0 字符——对蒸馏而言必然在解析阶段报废,改判为该路由失败而非返回空串);调用方主动取消不降级;每条路由各享**全额** `llm.timeoutMs`(共享预算会让慢 TTFT 的回退路由拿到的窗口小于它真实需要的首包时间,回退链形同虚设);token 成本逐次尝试记账(失败尝试也计一行,含流中断前已到的 token),成功调用归因到实际服务的路由。路由链也可在设置页 → 记忆 → 概览 → 蒸馏参数的「蒸馏路由链」编辑器里运行时调整(无需改配置重启);本 YAML 适合部署者固化静态链。
|
|
309
|
+
3. **调高超时**:`llm.timeoutMs` 只在路由确实慢但网关不掐时有用;网关 20s 掐断的场景调插件超时无效,请用前两层。
|
|
310
|
+
|
|
288
311
|
## 日志与故障排查
|
|
289
312
|
|
|
290
313
|
dsh 宿主把插件日志打到控制台;插件另把 info 级以上镜像到数据目录的 `memory.log`。
|