dsh-layered-memory 0.8.8 → 0.8.9

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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * 上下文占用账本:插件注入内容在当前会话上下文窗口中的启发式 token 存量。
3
+ *
4
+ * 本模块是全部占用数字的**唯一算术来源**(host 记账与 client 渲染共用,esbuild
5
+ * 将其内联进 client bundle),任何一侧不得另写算法。口径与官方
6
+ * @deepseek-ai/dsh-token-meter/estimate 的固定密度启发式同式:
7
+ *
8
+ * - text 块 = ceil(chars / 4) + 4(块开销);
9
+ * - 整条 user 消息(召回注入体的形态)再叠加 role overhead 4;
10
+ * - 系统提示里的稳定区**子片**计入时不加任何 overhead——那 +8 是官方对整段
11
+ * 消息/整体系统提示的结构成本,切片重复计会与官方总数对不上;
12
+ * - 字符数一律 JS `.length`(UTF-16 单元),与官方产出严格可比。
13
+ */
14
+ /** 固定文本密度:每 4 字符记 1 token(官方 CHARS_PER_TOKEN 同值)。 */
15
+ export declare const CHARS_PER_TOKEN = 4;
16
+ /** 召回注入体(单 text 块 user message)的启发式 token 数。 */
17
+ export declare function estimateInjectedMessageTokens(chars: number): number;
18
+ /** 稳定区子片的启发式 token 数(不加结构开销,见模块头注释)。 */
19
+ export declare function estimateStableSectionTokens(chars: number): number;
20
+ /**
21
+ * 单会话占用账本(权威账本只存在于 host 侧;client 仅消费展示)。
22
+ * stockTokens = recallTokens + profileTokens 恒等式由三个迁移函数共同维护。
23
+ */
24
+ export interface OccupancyLedger {
25
+ /** 当前估算仍在上下文窗口内的记忆存量(token)。 */
26
+ stockTokens: number;
27
+ /** 累计召回注入存留份额。 */
28
+ recallTokens: number;
29
+ /** 系统提示稳定区当前份额(OFF 使 text() 返回空时即时清零)。 */
30
+ profileTokens: number;
31
+ /** 最近一轮召回注入的增量(悬浮卡/面板"最近一次"语义)。 */
32
+ lastInjectTokens: number;
33
+ updatedAt: number;
34
+ }
35
+ export declare function emptyOccupancyLedger(now?: number): OccupancyLedger;
36
+ /** 召回注入成功后的入账(失败跳过的轮次不调用——账目零扰动)。 */
37
+ export declare function recordRecallInjection(l: OccupancyLedger, chars: number, now?: number): void;
38
+ /**
39
+ * 稳定区份额随每次实际组进的文本同步(含切回非 OFF 的重新计入):
40
+ * 增量记账保证重复调用不双算,清零后重设即可净额回补。
41
+ */
42
+ export declare function recordProfileShare(l: OccupancyLedger, chars: number, now?: number): void;
43
+ /** OFF 边界:稳定区随下一次请求组装物理离场,账目同边界清零(宁低勿高)。 */
44
+ export declare function clearProfileShare(l: OccupancyLedger, now?: number): void;
45
+ /**
46
+ * compaction 复位:v1 采用"清零重新累积"的低估近似——被压缩掉的注入以整数轮粒度
47
+ * 退出账本,幸存的摘要行不重复认领(已知限制,方向宁低勿高;事件级精确对齐留待 v2)。
48
+ */
49
+ export declare function resetForCompaction(l: OccupancyLedger, now?: number): void;
50
+ /**
51
+ * 官方上下文环周长:viewBox 14 内 r=5.5 圆(2π×5.5 ≈ 34.55751918948772),
52
+ * 与真机反推的官方 fill dasharray 分母逐字一致。
53
+ */
54
+ export declare const CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
55
+ /**
56
+ * 光晕弧 stroke-dasharray:形状沿用官方 fill(len + 全周长 gap)。
57
+ * @param occupancyRatio 占窗口比 0..1(越界钳制)。
58
+ * @param minLen 最小可见弧长(单位=-viewBox 坐标;14px 渲染下 <1 单位即亚像素不可见,
59
+ * 真实占比常低至 0.6%≈0.2 单位——指示灯语义需要"存在即可见",精确数字归面板)。
60
+ */
61
+ export declare function haloDashArray(occupancyRatio: number, circumference?: number, minLen?: number): string;
62
+ /** 官方环触发按钮的结构签名(locale 无关定位依据;见组件设计 C1 锚点节)。 */
63
+ export interface ContextMeterAnchorSignature {
64
+ ariaHasPopup?: string | null;
65
+ viewBox?: string | null;
66
+ circleRadii?: ReadonlyArray<number>;
67
+ }
68
+ export declare function isContextMeterAnchor(sig: ContextMeterAnchorSignature): boolean;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * 上下文占用账本:插件注入内容在当前会话上下文窗口中的启发式 token 存量。
3
+ *
4
+ * 本模块是全部占用数字的**唯一算术来源**(host 记账与 client 渲染共用,esbuild
5
+ * 将其内联进 client bundle),任何一侧不得另写算法。口径与官方
6
+ * @deepseek-ai/dsh-token-meter/estimate 的固定密度启发式同式:
7
+ *
8
+ * - text 块 = ceil(chars / 4) + 4(块开销);
9
+ * - 整条 user 消息(召回注入体的形态)再叠加 role overhead 4;
10
+ * - 系统提示里的稳定区**子片**计入时不加任何 overhead——那 +8 是官方对整段
11
+ * 消息/整体系统提示的结构成本,切片重复计会与官方总数对不上;
12
+ * - 字符数一律 JS `.length`(UTF-16 单元),与官方产出严格可比。
13
+ */
14
+ /** 固定文本密度:每 4 字符记 1 token(官方 CHARS_PER_TOKEN 同值)。 */
15
+ export const CHARS_PER_TOKEN = 4;
16
+ const BLOCK_OVERHEAD = 4;
17
+ const ROLE_OVERHEAD = 4;
18
+ /** 召回注入体(单 text 块 user message)的启发式 token 数。 */
19
+ export function estimateInjectedMessageTokens(chars) {
20
+ return Math.ceil(chars / CHARS_PER_TOKEN) + BLOCK_OVERHEAD + ROLE_OVERHEAD;
21
+ }
22
+ /** 稳定区子片的启发式 token 数(不加结构开销,见模块头注释)。 */
23
+ export function estimateStableSectionTokens(chars) {
24
+ return Math.ceil(chars / CHARS_PER_TOKEN);
25
+ }
26
+ export function emptyOccupancyLedger(now = Date.now()) {
27
+ return { stockTokens: 0, recallTokens: 0, profileTokens: 0, lastInjectTokens: 0, updatedAt: now };
28
+ }
29
+ /** 召回注入成功后的入账(失败跳过的轮次不调用——账目零扰动)。 */
30
+ export function recordRecallInjection(l, chars, now = Date.now()) {
31
+ const tokens = estimateInjectedMessageTokens(chars);
32
+ l.recallTokens += tokens;
33
+ l.stockTokens += tokens;
34
+ l.lastInjectTokens = tokens;
35
+ l.updatedAt = now;
36
+ }
37
+ /**
38
+ * 稳定区份额随每次实际组进的文本同步(含切回非 OFF 的重新计入):
39
+ * 增量记账保证重复调用不双算,清零后重设即可净额回补。
40
+ */
41
+ export function recordProfileShare(l, chars, now = Date.now()) {
42
+ const tokens = estimateStableSectionTokens(chars);
43
+ l.stockTokens += tokens - l.profileTokens;
44
+ l.profileTokens = tokens;
45
+ l.updatedAt = now;
46
+ }
47
+ /** OFF 边界:稳定区随下一次请求组装物理离场,账目同边界清零(宁低勿高)。 */
48
+ export function clearProfileShare(l, now = Date.now()) {
49
+ l.stockTokens -= l.profileTokens;
50
+ l.profileTokens = 0;
51
+ l.updatedAt = now;
52
+ }
53
+ /**
54
+ * compaction 复位:v1 采用"清零重新累积"的低估近似——被压缩掉的注入以整数轮粒度
55
+ * 退出账本,幸存的摘要行不重复认领(已知限制,方向宁低勿高;事件级精确对齐留待 v2)。
56
+ */
57
+ export function resetForCompaction(l, now = Date.now()) {
58
+ l.stockTokens = 0;
59
+ l.recallTokens = 0;
60
+ l.profileTokens = 0;
61
+ l.lastInjectTokens = 0;
62
+ l.updatedAt = now;
63
+ }
64
+ /* ── 渲染侧纯函数(client 寄生组件用;宿主 smoke 一并断言,数字唯一来源在此) ── */
65
+ /**
66
+ * 官方上下文环周长:viewBox 14 内 r=5.5 圆(2π×5.5 ≈ 34.55751918948772),
67
+ * 与真机反推的官方 fill dasharray 分母逐字一致。
68
+ */
69
+ export const CONTEXT_METER_CIRCUMFERENCE = 34.55751918948772;
70
+ /**
71
+ * 光晕弧 stroke-dasharray:形状沿用官方 fill(len + 全周长 gap)。
72
+ * @param occupancyRatio 占窗口比 0..1(越界钳制)。
73
+ * @param minLen 最小可见弧长(单位=-viewBox 坐标;14px 渲染下 <1 单位即亚像素不可见,
74
+ * 真实占比常低至 0.6%≈0.2 单位——指示灯语义需要"存在即可见",精确数字归面板)。
75
+ */
76
+ export function haloDashArray(occupancyRatio, circumference = CONTEXT_METER_CIRCUMFERENCE, minLen = 0) {
77
+ const clamped = Number.isFinite(occupancyRatio) ? Math.min(1, Math.max(0, occupancyRatio)) : 0;
78
+ const len = Math.max(clamped * circumference, clamped > 0 ? minLen : 0);
79
+ return `${len} ${circumference}`;
80
+ }
81
+ /** 半径比对容差:吞掉渲染库对属性值的无害浮点噪声。 */
82
+ const RADIUS_EPSILON = 1e-6;
83
+ export function isContextMeterAnchor(sig) {
84
+ if (sig.ariaHasPopup !== 'dialog')
85
+ return false;
86
+ if (sig.viewBox !== '0 0 14 14')
87
+ return false;
88
+ const radii = sig.circleRadii;
89
+ if (!Array.isArray(radii) || radii.length !== 2)
90
+ return false;
91
+ return radii.every((r) => Math.abs(r - 5.5) < RADIUS_EPSILON);
92
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-layered-memory",
3
- "version": "0.8.8",
3
+ "version": "0.8.9",
4
4
  "description": "L0~L3 分层蒸馏记忆插件 for DeepSeek Harness:自动捕获对话(L0)、抽取原子记忆(L1)、整合场景块(L2)、蒸馏核心画像/团队方法论(L3),并在模型步骤前自动召回注入。移植自 MemoryCore (TencentDB Agent Memory) 的管线设计。",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",