dsh-tdai-memory 0.2.13 → 0.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.
Files changed (72) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +15 -13
  3. package/README.zh.md +9 -7
  4. package/THIRD-PARTY-NOTICES.md +20 -20
  5. package/client.js +21 -4
  6. package/cordis.patch.yml +8 -8
  7. package/index.js +36 -14
  8. package/package.json +77 -78
  9. package/recall-inject.js +86 -86
  10. package/vendor/tdai/adapters/index.js +15 -15
  11. package/vendor/tdai/adapters/openclaw/host-adapter.js +83 -83
  12. package/vendor/tdai/adapters/openclaw/index.js +5 -5
  13. package/vendor/tdai/adapters/openclaw/llm-runner.js +69 -69
  14. package/vendor/tdai/adapters/standalone/host-adapter.js +58 -58
  15. package/vendor/tdai/adapters/standalone/index.js +5 -5
  16. package/vendor/tdai/adapters/standalone/llm-runner.js +34 -6
  17. package/vendor/tdai/config.js +3 -0
  18. package/vendor/tdai/core/conversation/l0-recorder.js +420 -420
  19. package/vendor/tdai/core/hooks/auto-capture.js +236 -236
  20. package/vendor/tdai/core/hooks/auto-recall.js +640 -640
  21. package/vendor/tdai/core/index.js +8 -8
  22. package/vendor/tdai/core/persona/persona-generator.js +184 -184
  23. package/vendor/tdai/core/persona/persona-trigger.js +94 -94
  24. package/vendor/tdai/core/profile/profile-sync.js +200 -200
  25. package/vendor/tdai/core/prompts/l1-dedup.js +72 -72
  26. package/vendor/tdai/core/prompts/l1-extraction.js +34 -34
  27. package/vendor/tdai/core/prompts/persona-generation.js +35 -35
  28. package/vendor/tdai/core/prompts/scene-extraction.js +45 -45
  29. package/vendor/tdai/core/record/l1-dedup.js +318 -318
  30. package/vendor/tdai/core/record/l1-extractor.js +379 -379
  31. package/vendor/tdai/core/record/l1-reader.js +178 -178
  32. package/vendor/tdai/core/record/l1-writer.js +141 -141
  33. package/vendor/tdai/core/report/reporter.js +86 -86
  34. package/vendor/tdai/core/scene/filename-normalizer.js +161 -161
  35. package/vendor/tdai/core/scene/scene-extractor.js +410 -410
  36. package/vendor/tdai/core/scene/scene-format.js +53 -53
  37. package/vendor/tdai/core/scene/scene-index.js +82 -82
  38. package/vendor/tdai/core/scene/scene-navigation.js +57 -57
  39. package/vendor/tdai/core/seed/input.js +404 -404
  40. package/vendor/tdai/core/seed/seed-runtime.js +4 -0
  41. package/vendor/tdai/core/seed/types.js +9 -9
  42. package/vendor/tdai/core/store/bm25-client.js +117 -117
  43. package/vendor/tdai/core/store/bm25-local.js +68 -68
  44. package/vendor/tdai/core/store/embedding.js +632 -632
  45. package/vendor/tdai/core/store/factory.js +95 -95
  46. package/vendor/tdai/core/store/search-utils.js +54 -54
  47. package/vendor/tdai/core/store/sqlite.js +1632 -1632
  48. package/vendor/tdai/core/store/tcvdb-client.js +221 -221
  49. package/vendor/tdai/core/store/tcvdb.js +1047 -1047
  50. package/vendor/tdai/core/store/types.js +17 -17
  51. package/vendor/tdai/core/tdai-core.js +4 -0
  52. package/vendor/tdai/core/tools/conversation-search.js +199 -199
  53. package/vendor/tdai/core/tools/memory-search.js +207 -207
  54. package/vendor/tdai/core/types.js +12 -12
  55. package/vendor/tdai/utils/backup.js +189 -189
  56. package/vendor/tdai/utils/checkpoint.js +360 -360
  57. package/vendor/tdai/utils/clean-context-runner.js +472 -472
  58. package/vendor/tdai/utils/ensure-hook-policy.js +213 -213
  59. package/vendor/tdai/utils/env.js +13 -13
  60. package/vendor/tdai/utils/managed-timer.js +127 -127
  61. package/vendor/tdai/utils/manifest.js +91 -91
  62. package/vendor/tdai/utils/memory-cleaner.js +300 -300
  63. package/vendor/tdai/utils/no-think-fetch.js +109 -109
  64. package/vendor/tdai/utils/openclaw-state-dir.js +26 -26
  65. package/vendor/tdai/utils/pipeline-factory.js +517 -517
  66. package/vendor/tdai/utils/pipeline-manager.js +892 -892
  67. package/vendor/tdai/utils/sanitize.js +360 -360
  68. package/vendor/tdai/utils/serial-queue.js +103 -103
  69. package/vendor/tdai/utils/session-filter.js +88 -88
  70. package/vendor/tdai/utils/session-header-fetch.js +88 -0
  71. package/vendor/tdai/utils/text-utils.js +29 -29
  72. package/vendor/tdai/utils/time.js +252 -252
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Scorp1o117
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Scorp1o117
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -76,6 +76,8 @@ tdai-memory:
76
76
  llm: # L1/L2/L3 extraction model (OpenAI-compatible)
77
77
  baseUrl: 'https://opencode.ai/zen/go/v1'
78
78
  model: 'mimo-v2.5' # deepseek-v4-flash produces invalid extraction JSON
79
+ sendSessionHeader: true # send x-opencode-session on LLM requests (required by OpenCode Go & similar gateways)
80
+ sessionId: '' # fixed session id; empty = persistent auto id under the data dir
79
81
  embedding: # vectors (OpenAI-compatible /v1/embeddings)
80
82
  baseUrl: 'http://127.0.0.1:8088/v1'
81
83
  model: 'Qwen3-Embedding-0.6B'
@@ -106,19 +108,19 @@ settings page (记忆 / Memory) or directly in `settings.yaml` under
106
108
  > - This plugin is a standard **profile bundle** (`dsh.bundle.patch`):
107
109
  > `dsh plugin --profile web add dsh-tdai-memory` installs and mounts it in
108
110
  > one step — no manual `cordis.patch.yml` edits needed.
109
- > - DSH exposes the registered `tdai-memory` settings namespace directly; the
110
- > plugin does not modify files in the host installation.
111
- > - Settings changes apply **after a restart** (TdaiCore is built at startup).
112
- > - Version 0.2.13 and newer require DSH `0.1.0-rc.7` or newer and are tested
113
- > against `0.1.0-rc.7`, `0.1.0-rc.8`, and `0.1.1-rc.1`.
114
- > - DSH `0.1.0-rc.6` users must pin `dsh-tdai-memory@0.2.11`, the last release
115
- > carrying the legacy settings-allowlist compatibility patch.
116
-
117
- `node-llama-cpp` is an optional peer used only by the fully local embedding
118
- backend. It is intentionally not installed by default because its native build
119
- requires explicit pnpm build approval. Remote OpenAI-compatible embeddings do
120
- not need it. Users who select the local backend should install and approve
121
- `node-llama-cpp` in the target DSH profile separately.
111
+ > - DSH exposes the registered `tdai-memory` settings namespace directly; the
112
+ > plugin does not modify files in the host installation.
113
+ > - Settings changes apply **after a restart** (TdaiCore is built at startup).
114
+ > - Version 0.2.13 and newer require DSH `0.1.0-rc.7` or newer and are tested
115
+ > against `0.1.0-rc.7`, `0.1.0-rc.8`, and `0.1.1-rc.1`.
116
+ > - DSH `0.1.0-rc.6` users must pin `dsh-tdai-memory@0.2.11`, the last release
117
+ > carrying the legacy settings-allowlist compatibility patch.
118
+
119
+ `node-llama-cpp` is an optional peer used only by the fully local embedding
120
+ backend. It is intentionally not installed by default because its native build
121
+ requires explicit pnpm build approval. Remote OpenAI-compatible embeddings do
122
+ not need it. Users who select the local backend should install and approve
123
+ `node-llama-cpp` in the target DSH profile separately.
122
124
 
123
125
  ## Known trade-offs
124
126
 
package/README.zh.md CHANGED
@@ -16,13 +16,13 @@
16
16
  - **自动召回注入**:每次组装提示词时,按当前用户消息检索相关记忆 + 画像,作为动态上下文注入(模型"凭空想起")
17
17
  - **工具**:`tdai_memory_search`(L1 结构化检索)、`tdai_conversation_search`(L0 原文检索)
18
18
 
19
- 数据目录复用现有 `~/.memory-tencentdb/memory-tdai`,**旧记忆无缝继承**。
20
-
21
- `node-llama-cpp` 仅供完全本地的 embedding 后端使用,现在声明为可选 peer,默认安装不会再触发原生构建脚本。使用 OpenAI 兼容远程 embedding 时不需要它;选择本地后端的用户需在目标 DSH profile 中单独安装并批准 `node-llama-cpp` 的构建。
22
-
23
- 从 `0.2.13` 起最低支持 DSH `0.1.0-rc.7`,已针对 `0.1.0-rc.7`、
24
- `0.1.0-rc.8` 和 `0.1.1-rc.1` 测试。仍使用 DSH `0.1.0-rc.6` 的用户请锁定
25
- `dsh-tdai-memory@0.2.11`;这是最后一个包含旧 settings 白名单兼容补丁的版本。
19
+ 数据目录复用现有 `~/.memory-tencentdb/memory-tdai`,**旧记忆无缝继承**。
20
+
21
+ `node-llama-cpp` 仅供完全本地的 embedding 后端使用,现在声明为可选 peer,默认安装不会再触发原生构建脚本。使用 OpenAI 兼容远程 embedding 时不需要它;选择本地后端的用户需在目标 DSH profile 中单独安装并批准 `node-llama-cpp` 的构建。
22
+
23
+ 从 `0.2.13` 起最低支持 DSH `0.1.0-rc.7`,已针对 `0.1.0-rc.7`、
24
+ `0.1.0-rc.8` 和 `0.1.1-rc.1` 测试。仍使用 DSH `0.1.0-rc.6` 的用户请锁定
25
+ `dsh-tdai-memory@0.2.11`;这是最后一个包含旧 settings 白名单兼容补丁的版本。
26
26
 
27
27
  ## 架构(移植方式)
28
28
 
@@ -63,6 +63,8 @@ tdai-memory:
63
63
  llm: # L1/L2/L3 提取模型(OpenAI 兼容)
64
64
  baseUrl: 'https://opencode.ai/zen/go/v1'
65
65
  model: 'mimo-v2.5' # deepseek-v4-flash 对提取 JSON 输出不合格
66
+ sendSessionHeader: true # 给 LLM 请求带 x-opencode-session(OpenCode Go 等网关要求)
67
+ sessionId: '' # 固定会话 ID;留空 = 数据目录下自动持久化 ID(重启不变)
66
68
  embedding: # 向量(OpenAI 兼容 /v1/embeddings)
67
69
  baseUrl: 'http://127.0.0.1:8088/v1'
68
70
  model: 'Qwen3-Embedding-0.6B'
@@ -1,20 +1,20 @@
1
- # Third-party notices
2
-
3
- ## TencentDB Agent Memory core (vendored in `vendor/tdai`)
4
-
5
- `vendor/tdai` is a TypeScript-compiled copy of the host-neutral core of
6
- [TencentCloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
7
- (`tdai-memory-openclaw-plugin`, npm: `@tencentdb-agent-memory/memory-tencentdb`),
8
- compiled with `tsc -p dsh-tsconfig.json` (see the upstream repo for source).
9
- Its runtime dependencies are declared in this package's `dependencies`.
10
-
11
- MIT License — Copyright (c) 2026 TencentCloud
12
-
13
- ## Runtime dependencies
14
-
15
- - `ai` / `@ai-sdk/openai` — Vercel AI SDK (Apache-2.0)
16
- - `@node-rs/jieba` — Rust jieba bindings (MIT)
17
- - `sqlite-vec` — vector search extension for SQLite (Apache-2.0 / MIT)
18
- - `json5` — JSON5 parser (MIT)
19
- - `undici` — HTTP client (MIT)
20
- - `@tencentdb-agent-memory/tcvdb-text` — TencentDB text utilities (MIT)
1
+ # Third-party notices
2
+
3
+ ## TencentDB Agent Memory core (vendored in `vendor/tdai`)
4
+
5
+ `vendor/tdai` is a TypeScript-compiled copy of the host-neutral core of
6
+ [TencentCloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)
7
+ (`tdai-memory-openclaw-plugin`, npm: `@tencentdb-agent-memory/memory-tencentdb`),
8
+ compiled with `tsc -p dsh-tsconfig.json` (see the upstream repo for source).
9
+ Its runtime dependencies are declared in this package's `dependencies`.
10
+
11
+ MIT License — Copyright (c) 2026 TencentCloud
12
+
13
+ ## Runtime dependencies
14
+
15
+ - `ai` / `@ai-sdk/openai` — Vercel AI SDK (Apache-2.0)
16
+ - `@node-rs/jieba` — Rust jieba bindings (MIT)
17
+ - `sqlite-vec` — vector search extension for SQLite (Apache-2.0 / MIT)
18
+ - `json5` — JSON5 parser (MIT)
19
+ - `undici` — HTTP client (MIT)
20
+ - `@tencentdb-agent-memory/tcvdb-text` — TencentDB text utilities (MIT)
package/client.js CHANGED
@@ -64,6 +64,11 @@ window.__ModuleLoader__.load({
64
64
  fieldLlmModel: "模型",
65
65
  fieldLlmMaxTokens: "最大输出 Tokens",
66
66
  fieldLlmTimeoutMs: "超时(毫秒)",
67
+ fieldLlmSendSessionHeader: "发送会话标识头(x-opencode-session)",
68
+ fieldLlmSessionHeaderName: "会话标识头名称",
69
+ fieldLlmSessionId: "固定会话 ID(留空 = 自动持久化)",
70
+ hintLlmSendSessionHeader: "OpenCode Go 等网关要求每个 LLM 请求带稳定的会话标识;请求不带可能报错(2026-09-06 起)。值:优先用固定 ID,否则在数据目录生成持久 ID(重启不变)。",
71
+ hintLlmSessionId: "后台抽取请求的固定会话标识;留空则自动生成并持久化到数据目录的 session-id 文件。",
67
72
  fieldEmbeddingBaseUrl: "Base URL",
68
73
  fieldEmbeddingApiKey: "API Key",
69
74
  fieldEmbeddingModel: "模型",
@@ -103,6 +108,11 @@ window.__ModuleLoader__.load({
103
108
  fieldLlmModel: "Model",
104
109
  fieldLlmMaxTokens: "Max output tokens",
105
110
  fieldLlmTimeoutMs: "Timeout (ms)",
111
+ fieldLlmSendSessionHeader: "Send session-id header (x-opencode-session)",
112
+ fieldLlmSessionHeaderName: "Session-id header name",
113
+ fieldLlmSessionId: "Fixed session id (empty = persistent auto)",
114
+ hintLlmSendSessionHeader: "OpenCode Go and similar gateways require a stable session id on every LLM request; requests without it may error (from 2026-09-06). Value: the fixed id below, else a persistent per-instance id stored under the data dir.",
115
+ hintLlmSessionId: "Fixed session id for background extraction requests; leave empty for a persistent auto id under the data dir (survives restarts).",
106
116
  fieldEmbeddingBaseUrl: "Base URL",
107
117
  fieldEmbeddingApiKey: "API Key",
108
118
  fieldEmbeddingModel: "Model",
@@ -135,6 +145,9 @@ window.__ModuleLoader__.load({
135
145
  { path: ["llm", "model"], label: "fieldLlmModel", type: "text", group: "groupLlm" },
136
146
  { path: ["llm", "maxTokens"], label: "fieldLlmMaxTokens", type: "number", group: "groupLlm" },
137
147
  { path: ["llm", "timeoutMs"], label: "fieldLlmTimeoutMs", type: "number", group: "groupLlm" },
148
+ { path: ["llm", "sendSessionHeader"], label: "fieldLlmSendSessionHeader", type: "checkbox", group: "groupLlm" },
149
+ { path: ["llm", "sessionHeaderName"], label: "fieldLlmSessionHeaderName", type: "text", group: "groupLlm" },
150
+ { path: ["llm", "sessionId"], label: "fieldLlmSessionId", type: "text", group: "groupLlm" },
138
151
  { path: ["embedding", "baseUrl"], label: "fieldEmbeddingBaseUrl", type: "text", group: "groupEmbedding" },
139
152
  { path: ["embedding", "apiKey"], label: "fieldEmbeddingApiKey", type: "password", secret: true, group: "groupEmbedding" },
140
153
  { path: ["embedding", "model"], label: "fieldEmbeddingModel", type: "text", group: "groupEmbedding" },
@@ -172,11 +185,15 @@ window.__ModuleLoader__.load({
172
185
  var [error, setError] = react.useState(null);
173
186
 
174
187
  react.useEffect(function () {
175
- if (typeof scope.load === "function") scope.load();
188
+ if (typeof scope.load === "function") scope.load();
176
189
  var alive = true;
177
190
  var sync = function () { if (alive) setSnapshot(scope.getSnapshot()); };
178
191
  var un = typeof scope.subscribe === "function" ? scope.subscribe(sync) : null;
179
- return function () { alive = false; if (un) un(); if (scope.dispose) scope.dispose(); };
192
+ // The settings scope is bound once for this plugin and shared across
193
+ // every mount of the section. Unmounting must only unsubscribe — never
194
+ // dispose the scope, or a later remount derives from a frozen (stopped)
195
+ // scope and shows stale values on the next describe.
196
+ return function () { alive = false; if (un) un(); };
180
197
  }, [scope]);
181
198
  // Initialize the draft ONLY when the snapshot becomes ready — never on
182
199
  // value churn. settingsScope.getSnapshot() returns a fresh object per
@@ -241,7 +258,7 @@ window.__ModuleLoader__.load({
241
258
  }
242
259
  setNotice(t("saved"));
243
260
  if (response.result.value) setDraft(Object.assign({}, valueToDraft(response.result.value)));
244
- if (typeof scope.load === "function") scope.load();
261
+ if (typeof scope.load === "function") scope.load();
245
262
  }).catch(function (e) {
246
263
  setBusy(false); setError(t("error") + ": " + String(e && e.message || e));
247
264
  });
@@ -258,7 +275,7 @@ window.__ModuleLoader__.load({
258
275
  if (!response.result.ok) { setError(t("error")); return; }
259
276
  setNotice(t("saved"));
260
277
  if (response.result.value) setDraft(Object.assign({}, valueToDraft(response.result.value)));
261
- if (typeof scope.load === "function") scope.load();
278
+ if (typeof scope.load === "function") scope.load();
262
279
  }).catch(function (e) {
263
280
  setBusy(false); setError(t("error") + ": " + String(e && e.message || e));
264
281
  });
package/cordis.patch.yml CHANGED
@@ -1,8 +1,8 @@
1
- # dsh-tdai-memory — bundle patch layer
2
- #
3
- # Declares the plugin as a Cordis loader entry, making the package a standard
4
- # profile bundle: `dsh plugin --profile <p> add dsh-tdai-memory` installs and
5
- # mounts it without manual cordis.patch.yml edits.
6
- - insert:
7
- - id: tdai-memory
8
- name: 'dsh-tdai-memory'
1
+ # dsh-tdai-memory — bundle patch layer
2
+ #
3
+ # Declares the plugin as a Cordis loader entry, making the package a standard
4
+ # profile bundle: `dsh plugin --profile <p> add dsh-tdai-memory` installs and
5
+ # mounts it without manual cordis.patch.yml edits.
6
+ - insert:
7
+ - id: tdai-memory
8
+ name: 'dsh-tdai-memory'
package/index.js CHANGED
@@ -21,7 +21,6 @@ import os from "node:os";
21
21
  import { join } from "node:path";
22
22
  import z from "@deepseek-ai/schemastery";
23
23
  import { defineTool } from "@deepseek-ai/dsh-tools";
24
- import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
25
24
  import { TdaiCore } from "./vendor/tdai/core/tdai-core.js";
26
25
  import { parseConfig } from "./vendor/tdai/config.js";
27
26
  import { StandaloneHostAdapter } from "./vendor/tdai/adapters/standalone/host-adapter.js";
@@ -31,7 +30,7 @@ const name = "tdai-memory";
31
30
  /** Services this row injects. */
32
31
  const inject = ["sessions", "systemPrompt", "tools"];
33
32
  /** Settings namespace owned by this plugin (Web UI settings section). */
34
- const NS = settingsNamespace("tdai-memory");
33
+ const NS = "tdai-memory";
35
34
 
36
35
  /** Runtime schema for the tdai-memory row. */
37
36
  const Config = z.object({
@@ -44,6 +43,15 @@ const Config = z.object({
44
43
  model: z.string().default(""),
45
44
  maxTokens: z.number().default(4096),
46
45
  timeoutMs: z.number().default(120000),
46
+ /** Send a stable session-id header on LLM requests. OpenCode Go and other
47
+ * gateways require `x-opencode-session` on every request; missing it may
48
+ * error after 2026-09-06. Value: `sessionId` below, else a persistent
49
+ * per-instance random id stored under the data dir. */
50
+ sendSessionHeader: z.boolean().default(true),
51
+ /** Header name carrying the session id. */
52
+ sessionHeaderName: z.string().default("x-opencode-session"),
53
+ /** Fixed session id for LLM requests; empty = persistent auto id. */
54
+ sessionId: z.string().default(""),
47
55
  }),
48
56
  /** Embedding endpoint (OpenAI-compatible /v1/embeddings). */
49
57
  embedding: z.object({
@@ -183,6 +191,9 @@ function apply(ctx, config) {
183
191
  model: cfg.llm.model || process.env.TDAI_LLM_MODEL || "deepseek-v4-flash",
184
192
  maxTokens: cfg.llm.maxTokens,
185
193
  timeoutMs: cfg.llm.timeoutMs,
194
+ sendSessionHeader: cfg.llm.sendSessionHeader,
195
+ sessionHeaderName: cfg.llm.sessionHeaderName,
196
+ sessionId: cfg.llm.sessionId,
186
197
  },
187
198
  });
188
199
  const nextHostAdapter = new StandaloneHostAdapter({
@@ -193,6 +204,10 @@ function apply(ctx, config) {
193
204
  model: nextConfig.llm.model,
194
205
  maxTokens: nextConfig.llm.maxTokens,
195
206
  timeoutMs: nextConfig.llm.timeoutMs,
207
+ sendSessionHeader: nextConfig.llm.sendSessionHeader,
208
+ sessionHeaderName: nextConfig.llm.sessionHeaderName,
209
+ sessionId: nextConfig.llm.sessionId,
210
+ dataDir,
196
211
  },
197
212
  logger,
198
213
  defaultUserId: "dsh-user",
@@ -365,20 +380,27 @@ function apply(ctx, config) {
365
380
 
366
381
  // ── settings-backed configuration ─────────────────────────────────────────
367
382
  // The composition entry stays the base layer; a registered `tdai-memory`
368
- // settings section overlays it (settings.yaml). `installSettingsSection`
369
- // hands `setSource` a GETTER (`() => scope.get()`), not the config object —
370
- // we must call it to obtain the resolved settings. The settings mount
371
- // (cordis inject) always arrives after our fallback timer, so the fallback
372
- // builds the core from the entry config first (one-shot) and the settings
373
- // build REBUILDS the core with the resolved values (apiKey included).
374
- installSettingsSection(ctx, NS, Config, config, {
375
- setSource: (getter) => {
383
+ // settings section overlays it (settings.yaml). The source is a GETTER
384
+ // (`() => scope.get()`), not the config object — we must call it to obtain
385
+ // the resolved settings. The settings mount (cordis inject) always arrives
386
+ // after our fallback timer, so the fallback builds the core from the entry
387
+ // config first (one-shot) and the settings build REBUILDS the core with the
388
+ // resolved values (apiKey included).
389
+ // Compat shim: dsh-settings 0.1.2-rc.1 removed the module-level
390
+ // `installSettingsSection` export (the provider now lives at ctx.settings).
391
+ // Inline the same logic via ctx.inject(["settings"]) — works on both
392
+ // 0.1.1 (module export wrapper) and 0.1.2 (ctx.settings) hosts.
393
+ ctx.inject(["settings"], (sctx) => {
394
+ const scope = sctx.settings.register(NS, Config, { base: config });
395
+ const fire = () => {
376
396
  builtOnce = true;
377
- void build(getter());
378
- },
379
- onChange: () => {
397
+ void build(scope.get());
398
+ };
399
+ sctx.effect(() => () => {});
400
+ fire();
401
+ scope.watch(() => {
380
402
  ctx.logger.warn("[tdai-memory] settings updated; restart to apply (TdaiCore is built at startup)");
381
- },
403
+ });
382
404
  });
383
405
 
384
406
  // Fallback when no settings service ever mounts: build from the entry
package/package.json CHANGED
@@ -1,79 +1,78 @@
1
1
  {
2
- "name": "dsh-tdai-memory",
3
- "version": "0.2.13",
4
- "description": "DeepSeek Harness 的 TencentDB Agent Memory 移植:L0 对话捕获 → L1 结构化记忆提取 → L2 场景/L3 画像,自动召回注入 + 记忆/对话搜索工具;复用现有 ~/.memory-tencentdb/memory-tdai 数据;附 Web UI 设置栏。",
5
- "type": "module",
6
- "main": "index.js",
7
- "exports": {
8
- ".": "./index.js",
9
- "./client": "./client.js",
10
- "./package.json": "./package.json"
11
- },
12
- "dsh": {
13
- "bundle": {
14
- "patch": "./cordis.patch.yml"
15
- },
16
- "client": {
17
- "platform": "web"
18
- }
19
- },
20
- "homepage": "https://github.com/Scorp1o117/dsh-tdai-memory",
21
- "files": [
22
- "index.js",
23
- "recall-inject.js",
24
- "client.js",
25
- "cordis.patch.yml",
26
- "vendor",
27
- "README.md",
28
- "README.zh.md",
29
- "LICENSE",
30
- "THIRD-PARTY-NOTICES.md"
31
- ],
32
- "keywords": [
33
- "dsh",
34
- "dsh-plugin",
35
- "deepseek-harness",
36
- "memory",
37
- "tencentdb",
38
- "agent-memory",
39
- "rag",
40
- "vector-search",
41
- "persona"
42
- ],
43
- "license": "MIT",
44
- "engines": {
45
- "node": "\u003e=22.18"
46
- },
47
- "repository": {
48
- "type": "git",
49
- "url": "git+https://github.com/Scorp1o117/dsh-tdai-memory.git"
50
- },
51
- "bugs": {
52
- "url": "https://github.com/Scorp1o117/dsh-tdai-memory/issues"
53
- },
54
- "dependencies": {
55
- "@ai-sdk/openai": "^3.0.53",
56
- "@deepseek-ai/schemastery": "^3.18.1",
57
- "@node-rs/jieba": "^2.0.1",
58
- "@tencentdb-agent-memory/tcvdb-text": "^0.1.1",
59
- "ai": "^6.0.164",
60
- "json5": "^2.2.3",
61
- "sqlite-vec": "0.1.7-alpha.2",
62
- "undici": "^8.1.0"
63
- },
64
- "peerDependencies": {
65
- "react": "^18.2.0",
66
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.1",
67
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.7 || ^0.1.1-rc.1",
68
- "node-llama-cpp": "^3.19.1"
69
- },
70
- "peerDependenciesMeta": {
71
- "node-llama-cpp": {
72
- "optional": true
73
- }
74
- },
75
- "scripts": {
76
- "test": "node tests/settings-scope-compat.test.mjs && node tests/install-contract.test.mjs"
77
- }
78
- }
79
-
2
+ "name": "dsh-tdai-memory",
3
+ "version": "0.3.0",
4
+ "description": "DeepSeek Harness 的 TencentDB Agent Memory 移植:L0 对话捕获 → L1 结构化记忆提取 → L2 场景/L3 画像,自动召回注入 + 记忆/对话搜索工具;复用现有 ~/.memory-tencentdb/memory-tdai 数据;附 Web UI 设置栏。",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "exports": {
8
+ ".": "./index.js",
9
+ "./client": "./client.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "dsh": {
13
+ "bundle": {
14
+ "patch": "./cordis.patch.yml"
15
+ },
16
+ "client": {
17
+ "platform": "web"
18
+ }
19
+ },
20
+ "homepage": "https://github.com/Scorp1o117/dsh-tdai-memory",
21
+ "files": [
22
+ "index.js",
23
+ "recall-inject.js",
24
+ "client.js",
25
+ "cordis.patch.yml",
26
+ "vendor",
27
+ "README.md",
28
+ "README.zh.md",
29
+ "LICENSE",
30
+ "THIRD-PARTY-NOTICES.md"
31
+ ],
32
+ "keywords": [
33
+ "dsh",
34
+ "dsh-plugin",
35
+ "deepseek-harness",
36
+ "memory",
37
+ "tencentdb",
38
+ "agent-memory",
39
+ "rag",
40
+ "vector-search",
41
+ "persona"
42
+ ],
43
+ "license": "MIT",
44
+ "engines": {
45
+ "node": ">=22.18"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/Scorp1o117/dsh-tdai-memory.git"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/Scorp1o117/dsh-tdai-memory/issues"
53
+ },
54
+ "dependencies": {
55
+ "@ai-sdk/openai": "^3.0.53",
56
+ "@deepseek-ai/schemastery": "^3.18.1",
57
+ "@node-rs/jieba": "^2.0.1",
58
+ "@tencentdb-agent-memory/tcvdb-text": "^0.1.1",
59
+ "ai": "^6.0.164",
60
+ "json5": "^2.2.3",
61
+ "sqlite-vec": "0.1.7-alpha.2",
62
+ "undici": "^8.1.0"
63
+ },
64
+ "peerDependencies": {
65
+ "react": "^18.2.0",
66
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-rc.1",
67
+ "@deepseek-ai/dsh-settings": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-rc.1",
68
+ "node-llama-cpp": "^3.19.1"
69
+ },
70
+ "peerDependenciesMeta": {
71
+ "node-llama-cpp": {
72
+ "optional": true
73
+ }
74
+ },
75
+ "scripts": {
76
+ "test": "node tests/settings-scope-compat.test.mjs && node tests/install-contract.test.mjs"
77
+ }
78
+ }