@zooique/memora 5.1.0 → 5.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.
- package/CHANGELOG.md +107 -4
- package/README.en.md +6 -2
- package/README.md +6 -2
- package/dist/agent/agent.d.ts +42 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +61 -3
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +7 -0
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/constants.d.ts +49 -0
- package/dist/agent/constants.d.ts.map +1 -1
- package/dist/agent/constants.js +49 -0
- package/dist/agent/constants.js.map +1 -1
- package/dist/agent/contextManager.d.ts +31 -3
- package/dist/agent/contextManager.d.ts.map +1 -1
- package/dist/agent/contextManager.js +39 -2
- package/dist/agent/contextManager.js.map +1 -1
- package/dist/agent/loop.d.ts +14 -7
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +43 -18
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/llmCaller.d.ts.map +1 -1
- package/dist/agent/managers/llmCaller.js +14 -1
- package/dist/agent/managers/llmCaller.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +1 -0
- package/dist/agent/managers/sessionManager.js.map +1 -1
- package/dist/agent/managers/toolCallHelpers.d.ts.map +1 -1
- package/dist/agent/managers/toolCallHelpers.js +3 -0
- package/dist/agent/managers/toolCallHelpers.js.map +1 -1
- package/dist/agent/messageHistory.d.ts +86 -16
- package/dist/agent/messageHistory.d.ts.map +1 -1
- package/dist/agent/messageHistory.js +203 -65
- package/dist/agent/messageHistory.js.map +1 -1
- package/dist/agent/seed/orchestrator.d.ts +2 -1
- package/dist/agent/seed/orchestrator.d.ts.map +1 -1
- package/dist/agent/seed/orchestrator.js +48 -17
- package/dist/agent/seed/orchestrator.js.map +1 -1
- package/dist/agent/seed/prepare.d.ts +3 -1
- package/dist/agent/seed/prepare.d.ts.map +1 -1
- package/dist/agent/seed/prepare.js +10 -2
- package/dist/agent/seed/prepare.js.map +1 -1
- package/dist/agent/sessionStateMachine.d.ts +3 -0
- package/dist/agent/sessionStateMachine.d.ts.map +1 -1
- package/dist/agent/sessionStateMachine.js.map +1 -1
- package/dist/agent/textSanitize.d.ts +1 -1
- package/dist/agent/textSanitize.js +1 -1
- package/dist/agent/types.d.ts +9 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/llm/factory.d.ts +21 -0
- package/dist/llm/factory.d.ts.map +1 -1
- package/dist/llm/factory.js +4 -1
- package/dist/llm/factory.js.map +1 -1
- package/dist/llm/openaiCompatible.d.ts +8 -1
- package/dist/llm/openaiCompatible.d.ts.map +1 -1
- package/dist/llm/openaiCompatible.js +26 -0
- package/dist/llm/openaiCompatible.js.map +1 -1
- package/dist/llm/provider.d.ts +65 -0
- package/dist/llm/provider.d.ts.map +1 -1
- package/dist/llm/provider.js +10 -0
- package/dist/llm/provider.js.map +1 -1
- package/dist/memory/gcService.d.ts +8 -4
- package/dist/memory/gcService.d.ts.map +1 -1
- package/dist/memory/gcService.js.map +1 -1
- package/dist/memory/inMemoryRoundStore.d.ts +8 -3
- package/dist/memory/inMemoryRoundStore.d.ts.map +1 -1
- package/dist/memory/inMemoryRoundStore.js +19 -10
- package/dist/memory/inMemoryRoundStore.js.map +1 -1
- package/dist/memory/inMemorySessionStore.d.ts.map +1 -1
- package/dist/memory/inMemorySessionStore.js +11 -0
- package/dist/memory/inMemorySessionStore.js.map +1 -1
- package/dist/memory/roundStore.d.ts +84 -11
- package/dist/memory/roundStore.d.ts.map +1 -1
- package/dist/memory/roundStore.js +18 -0
- package/dist/memory/roundStore.js.map +1 -1
- package/dist/memory/sessionStore.d.ts +8 -0
- package/dist/memory/sessionStore.d.ts.map +1 -1
- package/dist/memory/sessionStore.js.map +1 -1
- package/dist/utils/time.d.ts +24 -4
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +32 -4
- package/dist/utils/time.js.map +1 -1
- package/docs/memora-api-reference.md +14 -4
- package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +45 -17
- package/package.json +5 -2
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* 所有会话在存储层平等。
|
|
7
7
|
*/
|
|
8
8
|
import type { MessageRole } from '../memory/types.js';
|
|
9
|
+
import type { ImageRef } from '../llm/provider.js';
|
|
9
10
|
import type { AbortStopReason, LlmErrorCategory } from '../agent/types.js';
|
|
10
11
|
/**
|
|
11
12
|
* 问答闭环消息:与 LLM Message 兼容,额外带持久化所需时间戳。
|
|
@@ -24,6 +25,12 @@ export interface RoundMessage {
|
|
|
24
25
|
input: number;
|
|
25
26
|
output: number;
|
|
26
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* 图片附件引用(可选,多模态输入)。仅 user 消息持有;
|
|
30
|
+
* 整对象 JSON 天然带走(零 IO 改造),但 `MessageHistory.appendUser` 的
|
|
31
|
+
* `userMessage` 白名单必须显式拷此字段(方案 §7 P0-12)。
|
|
32
|
+
*/
|
|
33
|
+
attachments?: readonly ImageRef[];
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* 交互输入类型(问答闭环内交互输入归属)
|
|
@@ -37,8 +44,36 @@ export interface RoundMessage {
|
|
|
37
44
|
* - timeout:ask_user 提问超时未答(宿主计时超时 → cancelAsk 注入
|
|
38
45
|
* [ASK_ABORTED] 占位 + resumeExecution('timeout') 自动续跑,LLM 自决;记录带
|
|
39
46
|
* question/options 供重放渲染「问 + 未回答」行)
|
|
47
|
+
* - unanswered:「问了没答」的兜底形态,两个生产者——① 提问挂起后崩溃/中断,重启打捞
|
|
48
|
+
* (或运行期非正常收场)时把轮上残留的 `pendingAsk` 整组转化(appendInterrupted);
|
|
49
|
+
* ② 作答批次内被跳过的题(orchestrator.runResume,ASK-MULTI-Q-1,正文=ASK_ABORTED_RESULT
|
|
50
|
+
* 占位、可与同批 question-answer 条目交错)——与 timeout 同为「问了没答」,成因各自诚实
|
|
51
|
+
* 分型,防「数据迁就渲染」撒谎
|
|
52
|
+
*/
|
|
53
|
+
export type InteractiveInputKind = 'question-answer' | 'supplement' | 'timeout' | 'unanswered';
|
|
54
|
+
/**
|
|
55
|
+
* 在途提问快照(Round.pendingAsk 元素)
|
|
56
|
+
*
|
|
57
|
+
* 提问挂起(yield paused)**之前**由内核写入当前轮并随 Round 落盘——「AI 已提问、用户未答」
|
|
58
|
+
* 时崩溃,问题文本不再只活在进程内存(E2E-ASK-LOSS-1 修复)。形状刻意窄于内核
|
|
59
|
+
* `AskQuestion`(slot/allowCustom 是交互期参数,历史重放不消费):落盘只留
|
|
60
|
+
* 「问了什么 + 候选选项」两个重放必需面。
|
|
61
|
+
*
|
|
62
|
+
* 生命周期不变量:**非空 ⇔ 该轮存在「问了但未答且作答记录未落盘」的窗口**。
|
|
63
|
+
* 三个对称消费点保证其成立——
|
|
64
|
+
* - 写入:`MessageHistory.markPendingAsk`(挂起前,装配层经 onPendingQuestion 调用);
|
|
65
|
+
* - 原子清除:`MessageHistory.appendUser` 交互分支(ask 消费记录落盘——question-answer/
|
|
66
|
+
* timeout/unanswered 任一形态,含批次内全跳过——的同一次 save 内清,无双记录窗口);
|
|
67
|
+
* - 收场转化:`MessageHistory.appendInterrupted` 把非空的 pendingAsk 转成
|
|
68
|
+
* `kind:'unanswered'` 的 interactiveInputs 条目并清字段(打捞/运行期失败统一受益)。
|
|
69
|
+
* 正常完成收场(appendAssistant)防御性清空(此时作答记录已落,残留即脏数据)。
|
|
40
70
|
*/
|
|
41
|
-
export
|
|
71
|
+
export interface RoundPendingAsk {
|
|
72
|
+
/** 提问原文 */
|
|
73
|
+
question: string;
|
|
74
|
+
/** 候选选项(ask_user options 参数;LLM 未提供时缺省) */
|
|
75
|
+
options?: string[];
|
|
76
|
+
}
|
|
42
77
|
/**
|
|
43
78
|
* 问答闭环内交互输入(Round.interactiveInputs 元素)
|
|
44
79
|
*
|
|
@@ -77,8 +112,9 @@ export interface RoundInteractiveInput extends RoundMessage {
|
|
|
77
112
|
* - **实现落点**:`seed/orchestrator.act()`(中断 aborted / 失败 failed 收口到同一尾处理)
|
|
78
113
|
* → `history.appendInterrupted` 写 `status:'interrupted'`。
|
|
79
114
|
* - **打捞关系**:`listInterruptedRecent`(内核 + 宿主两端)打捞条件仍为 `pending || error`,
|
|
80
|
-
* **不含 interrupted
|
|
81
|
-
*
|
|
115
|
+
* **不含 interrupted**——interrupted 是「已收场的停 turn」,本就不属崩溃残留。
|
|
116
|
+
* ⚠️ ADR-044 起新建轮**建轮即 refCount 1 并登记会话**,故「`refCount===0` 才需要打捞」这一
|
|
117
|
+
* 理由只对存量轮成立;新数据的打捞意义从「让它可见」变为「把 pending 收场为 interrupted」。
|
|
82
118
|
*
|
|
83
119
|
* ⚠️ 关于 `error`(防未来误判):
|
|
84
120
|
* - **不存在** `pending → error` 的流转——全仓 grep 零写点(生产代码);运行时失败走
|
|
@@ -109,6 +145,22 @@ export type RoundStatus = 'pending' | 'complete' | 'error' | 'interrupted';
|
|
|
109
145
|
* @returns 该轮是否已进入终态(可作后续上下文)
|
|
110
146
|
*/
|
|
111
147
|
export declare function isRoundSettled(status: RoundStatus): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* 轮是否「成功收场」——**成功判据单一收口点(SSOT)**。
|
|
150
|
+
*
|
|
151
|
+
* 与 `isRoundSettled` 的分野(勿混用):`isRoundSettled` 回答「这轮还能不能当上下文用」,
|
|
152
|
+
* 本函数回答「这轮算不算跑成功」。`interrupted` 是**定案**的正常收场(等同用户点停止,
|
|
153
|
+
* 见 `isRoundSettled` 的语义定案),但**不等于成功**——它的正文可能是失败兜底 / 被打断。
|
|
154
|
+
*
|
|
155
|
+
* **为什么必须收口**:当前唯一消费面是宿主 `metrics.success`(执行指标「流程跑完了没有」,
|
|
156
|
+
* 盘面缺失时降级为进程内口径);凡将来新增「这轮算不算成功」的读取方,**一律调用本函数**,
|
|
157
|
+
* 不得自写 `status === 'complete'`(第二真相源)。宿主侧自写比较已被 `roundStore.test.ts`
|
|
158
|
+
* 的判据单源守卫拦过——`occupancyHistory.ts` 因此把收场判据改用 `isRoundSettled`。
|
|
159
|
+
*
|
|
160
|
+
* @param status - 轮状态
|
|
161
|
+
* @returns 该轮是否成功收场(仅 `complete`)
|
|
162
|
+
*/
|
|
163
|
+
export declare function isRoundSuccessful(status: RoundStatus): boolean;
|
|
112
164
|
/**
|
|
113
165
|
* 思考阶段值(与 agent ThinkingPhase 同值的本地字面量,解耦依赖方向)
|
|
114
166
|
*
|
|
@@ -526,6 +578,14 @@ export interface Round {
|
|
|
526
578
|
* 此数组仅承载用户侧交互输入,供重放渲染折叠的「用户提问 / 用户补充」块。
|
|
527
579
|
*/
|
|
528
580
|
interactiveInputs?: RoundInteractiveInput[];
|
|
581
|
+
/**
|
|
582
|
+
* 在途提问快照(挂起前落盘,E2E-ASK-LOSS-1)
|
|
583
|
+
*
|
|
584
|
+
* 「AI 已提问、用户未答」窗口内崩溃,问题文本与候选选项仍可从盘上恢复。
|
|
585
|
+
* 生命周期不变量与三个对称消费点见 `RoundPendingAsk` 注释;收场时由
|
|
586
|
+
* appendInterrupted 转成 `kind:'unanswered'` 交互输入,终态轮不残留本字段。
|
|
587
|
+
*/
|
|
588
|
+
pendingAsk?: RoundPendingAsk[];
|
|
529
589
|
/**
|
|
530
590
|
* 裁决证据(悬案取证轨)
|
|
531
591
|
*
|
|
@@ -549,6 +609,10 @@ export interface Round {
|
|
|
549
609
|
completedAt?: string;
|
|
550
610
|
/**
|
|
551
611
|
* 引用计数(被多少个会话引用):分叉 +1、删除会话 −1、**归零即可被 GC 清理**。
|
|
612
|
+
*
|
|
613
|
+
* ⚠️ ADR-044 起:**建轮即 1**(创建它的会话立刻引用它),收场不再 +1。
|
|
614
|
+
* 因此「refCount 0」不再表示「尚未完成」,只表示「没有任何会话持有它」——
|
|
615
|
+
* 后者仅出现在存量轮(ADR-044 之前落盘)或建轮时登记失败的异常残留上。
|
|
552
616
|
*/
|
|
553
617
|
refCount: number;
|
|
554
618
|
/**
|
|
@@ -631,24 +695,33 @@ export interface IRoundStore {
|
|
|
631
695
|
/**
|
|
632
696
|
* 获取孤立的问答闭环列表(refCount === 0)
|
|
633
697
|
*
|
|
634
|
-
* 用于 GC
|
|
698
|
+
* 用于 GC 服务批量清理。
|
|
699
|
+
*
|
|
700
|
+
* ⚠️ 判据语义(ADR-044 第四刀确认):`refCount === 0` = **真正无人引用**。
|
|
701
|
+
* ADR-044 起建轮即 `refCount: 1`,故「进行中(pending)」本身**不再**构成孤儿判据——
|
|
702
|
+
* 已入会话的轮不会被超龄静默回收;能落到 0 的只有:存量轮(ADR-044 之前落盘)、
|
|
703
|
+
* 删会话/截断后归零的轮、归属登记失败的残留(后者为已知取舍,不可见但保留、不自动回收)。
|
|
635
704
|
*
|
|
636
|
-
* @param minAgeMs -
|
|
705
|
+
* @param minAgeMs - 最小存活时间(毫秒):给刚归零的轮留后悔窗口,**不是**「防误清在途轮」
|
|
637
706
|
* @returns 孤立 Round 数组
|
|
638
707
|
*/
|
|
639
708
|
listOrphaned?(minAgeMs?: number): Round[];
|
|
640
709
|
/**
|
|
641
710
|
* 列出指定日期最近未完成(pending/error)的崩溃残留轮(step 原子落盘)。
|
|
642
711
|
*
|
|
643
|
-
* 用途:崩溃残留轮升级前的**只读中转**——崩溃发生在 appendAssistant
|
|
644
|
-
*
|
|
645
|
-
* 落盘;宿主重启后经此口查回,再调 `MessageHistory.appendInterrupted` 升级为正常 stop turn。
|
|
712
|
+
* 用途:崩溃残留轮升级前的**只读中转**——崩溃发生在 appendAssistant 完成前时,宿主要靠它
|
|
713
|
+
* 找回这些轮,再调 `MessageHistory.appendInterrupted` 收场为正常 stop turn。
|
|
646
714
|
*
|
|
647
715
|
* 语义约束(SSOT):① **只读**——不登记会话、不改写 Round、不改变 appendAssistant 完成语义;
|
|
648
|
-
* ②
|
|
649
|
-
*
|
|
716
|
+
* ② **不改变可见性判定**——轮是否已入会话由 `refCount` 表达(ADR-044 起建轮即 1),
|
|
717
|
+
* 本方法不负责「让它可见」;
|
|
718
|
+
* ③ 不改变生命周期——⚠️ ADR-044 后新建的 pending 轮 `refCount === 1`,**不再落进
|
|
719
|
+
* `sweepOrphans` 的 `refCount===0` 判据**,故不会被超龄回收(可见即可由用户删除)。
|
|
720
|
+
* 该口径已在 ADR-044 第四刀确认(判据保持不变,语义收窄为「真正无人引用」)。
|
|
650
721
|
*
|
|
651
|
-
* @param date - YYYY-MM-DD
|
|
722
|
+
* @param date - YYYY-MM-DD **本地日期**(与会话 ID 日期同口径):按本地日区间
|
|
723
|
+
* `[D 00:00, D+1 00:00)` 换算 UTC 后比较 createdAt,判据单点 = `isWithinLocalDay`
|
|
724
|
+
* (两道实现同源;前缀匹配在 UTC+8 凌晨窗口漏捞,E2E-TZ-SALVAGE-1)
|
|
652
725
|
* @param limit - 最多返回条数,按 createdAt 降序(最新在前);缺省不截断
|
|
653
726
|
* @returns 中断残留 Round 数组(按 createdAt 倒序)
|
|
654
727
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roundStore.d.ts","sourceRoot":"","sources":["../../src/memory/roundStore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAI1E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,WAAW,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;IAEhB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAElB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;
|
|
1
|
+
{"version":3,"file":"roundStore.d.ts","sourceRoot":"","sources":["../../src/memory/roundStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,24 @@
|
|
|
27
27
|
export function isRoundSettled(status) {
|
|
28
28
|
return status === 'complete' || status === 'interrupted';
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* 轮是否「成功收场」——**成功判据单一收口点(SSOT)**。
|
|
32
|
+
*
|
|
33
|
+
* 与 `isRoundSettled` 的分野(勿混用):`isRoundSettled` 回答「这轮还能不能当上下文用」,
|
|
34
|
+
* 本函数回答「这轮算不算跑成功」。`interrupted` 是**定案**的正常收场(等同用户点停止,
|
|
35
|
+
* 见 `isRoundSettled` 的语义定案),但**不等于成功**——它的正文可能是失败兜底 / 被打断。
|
|
36
|
+
*
|
|
37
|
+
* **为什么必须收口**:当前唯一消费面是宿主 `metrics.success`(执行指标「流程跑完了没有」,
|
|
38
|
+
* 盘面缺失时降级为进程内口径);凡将来新增「这轮算不算成功」的读取方,**一律调用本函数**,
|
|
39
|
+
* 不得自写 `status === 'complete'`(第二真相源)。宿主侧自写比较已被 `roundStore.test.ts`
|
|
40
|
+
* 的判据单源守卫拦过——`occupancyHistory.ts` 因此把收场判据改用 `isRoundSettled`。
|
|
41
|
+
*
|
|
42
|
+
* @param status - 轮状态
|
|
43
|
+
* @returns 该轮是否成功收场(仅 `complete`)
|
|
44
|
+
*/
|
|
45
|
+
export function isRoundSuccessful(status) {
|
|
46
|
+
return status === 'complete';
|
|
47
|
+
}
|
|
30
48
|
// ─── 辅助函数 ───────────────────────────────────────────
|
|
31
49
|
/** 生成 Round ID(格式:round-{uuid}) */
|
|
32
50
|
export function generateRoundId() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roundStore.js","sourceRoot":"","sources":["../../src/memory/roundStore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"roundStore.js","sourceRoot":"","sources":["../../src/memory/roundStore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA0IH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,aAAa,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,OAAO,MAAM,KAAK,UAAU,CAAC;AAC/B,CAAC;AAmiBD,uDAAuD;AAEvD,mCAAmC;AACnC,MAAM,UAAU,eAAe;IAC7B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,SAAS,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IACxC,CAAC;IACD,iBAAiB;IACjB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,SAAS,SAAS,GAAG,MAAM,EAAE,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,OAAO,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,OAAO,SAAS,GAAG,MAAM,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO;QACL,EAAE;QACF,WAAW,EAAE;YACX,EAAE,EAAE,iBAAiB,EAAE;YACvB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,WAAW;YACpB,SAAS,EAAE,GAAG;SACf;QACD,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,GAAG;QACd,QAAQ,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAY,EACZ,gBAAwB,EACxB,UAA8C;IAE9C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO;QACL,GAAG,KAAK;QACR,gBAAgB,EAAE;YAChB,EAAE,EAAE,iBAAiB,EAAE;YACvB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,GAAG;YACd,UAAU;SACX;QACD,MAAM,EAAE,UAAU;QAClB,WAAW,EAAE,GAAG;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MessageRole } from '../memory/types.js';
|
|
2
|
+
import type { ImageRef } from '../llm/provider.js';
|
|
2
3
|
/**
|
|
3
4
|
* 会话存储接口:宿主注入的会话消息持久化能力,内核不直接依赖文件 I/O。
|
|
4
5
|
* IMemoryStorage 存记忆索引(round-summary),这里存原始对话消息。零依赖内核、接口最小化、不实现则走内存模式。
|
|
@@ -16,6 +17,11 @@ export interface ISessionStore {
|
|
|
16
17
|
* 落盘 + 单条上限),历史回注(`restoreHistory` ← 本方法)不含 tool。两个实现(宿主
|
|
17
18
|
* `hosts/memora-vscode/.../host/sessionStore.ts`、内核 `inMemorySessionStore.ts`)逐字同构。
|
|
18
19
|
*
|
|
20
|
+
* **user 消息必须带 `attachments`,且经 `LOOP_CONSTANTS.RETAIN_IMAGE_ROUNDS` 窗口衰减**
|
|
21
|
+
* (判据与 `messageHistory.loadRoundBasedMessages` 同构:仅最近窗口内轮次带图,content 不变)。
|
|
22
|
+
* 本方法是 restoreHistory 生产路径唯一上游——漏带 = 重启后历史图全灭(真机验收 IMG-2
|
|
23
|
+
* 第 13 子块断点B实锤:模型只见纯文本连占位都没有);漏衰减 = 窗口外图片灌爆上下文。
|
|
24
|
+
*
|
|
19
25
|
* ⚠️ 改此契约(如让 tool 消息也入历史)须同步评估大文本统一通道 §6.2:
|
|
20
26
|
* 压缩链的「超大 tool 结果卸载级」正是因本契约而删除(读者先亡 → 写者后死);若历史重新携带
|
|
21
27
|
* tool 消息,该级的存在前提会复活。
|
|
@@ -106,5 +112,7 @@ export interface SessionMessage {
|
|
|
106
112
|
timestamp: string;
|
|
107
113
|
/** 所属轮次 ID(可选):traceSummary 精确回溯用,空则退化为整会话摘要 */
|
|
108
114
|
roundId?: string;
|
|
115
|
+
/** 图片附件引用(可选,多模态输入);对话占用环与序列化共享同一数据 */
|
|
116
|
+
attachments?: readonly ImageRef[];
|
|
109
117
|
}
|
|
110
118
|
//# sourceMappingURL=sessionStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/memory/sessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/memory/sessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAE5B;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAAC;IAG9D,mCAAmC;IACnC,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,gCAAgC;IAChC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAC3D,oEAAoE;IACpE,eAAe,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzD,oDAAoD;IACpD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACvE;;;;;OAKG;IACH,gBAAgB,IAAI,WAAW,EAAE,CAAC;IAGlC,sBAAsB;IACtB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,+BAA+B;IAC/B,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5D,wBAAwB;IACxB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,qCAAqC;IACrC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACzD,eAAe;IACf,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACvC,6BAA6B;IAC7B,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAGlB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,YAAY,EAAE,MAAM,CAAC;IAGrB;;;;;;;;;;;;;;;OAeG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAS3E;AAED,gCAAgC;AAChC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAIxE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,WAAW,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionStore.js","sourceRoot":"","sources":["../../src/memory/sessionStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sessionStore.js","sourceRoot":"","sources":["../../src/memory/sessionStore.ts"],"names":[],"mappings":"AAiHA;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA6B;IACjE,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,wBAAwB;IACxB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,wBAAwB;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,kBAAkB,CAAC,IAA6B;IAC9D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvC,OAAO,QAAQ,IAAI,EAAE,CAAC;AACxB,CAAC"}
|
package/dist/utils/time.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 时间工具函数
|
|
3
3
|
*
|
|
4
|
-
* 从 messageHistory.ts
|
|
4
|
+
* 从 messageHistory.ts 提取的公共时间格式化函数。大部分仍为内核 `src/` 内部入口;
|
|
5
|
+
* `formatDateKey` / `todayDate` / `isWithinLocalDay` 经 `src/index.ts` 挂公开面供宿主复用
|
|
6
|
+
* (宿主消费前先过 publicApiSurfaceGuard 登记)。
|
|
5
7
|
*
|
|
6
|
-
* ⚠️
|
|
7
|
-
*
|
|
8
|
-
* 本文件只是内核内部的推荐入口,不是跨包单一真源。
|
|
8
|
+
* ⚠️ `nowIso` **未**进 `src/index.ts` 公开导出面,宿主拿不到它
|
|
9
|
+
* (实测宿主 `nowIso` 引用 = 0),宿主侧取当前时间仍是各自内联。
|
|
9
10
|
*
|
|
10
11
|
* API 对齐(历史):formatDateKey(date) 曾与精灵宿主 shared/dateUtils.ts 语义一致(该宿主已移除),
|
|
11
12
|
* 用于格式化任意 Date 为 YYYY-MM-DD(本地时区)。
|
|
@@ -40,6 +41,25 @@ export declare function formatDateKey(date: Date): string;
|
|
|
40
41
|
* @returns 如 "2026-06-21"
|
|
41
42
|
*/
|
|
42
43
|
export declare function todayDate(): string;
|
|
44
|
+
/**
|
|
45
|
+
* 判定 UTC ISO 时间戳是否落在指定**本地日期**的一天内(本地日区间 `[D 00:00, D+1 00:00)` → UTC 比较)。
|
|
46
|
+
*
|
|
47
|
+
* 为什么不能按日期头前缀匹配(E2E-TZ-SALVAGE-1 血训):会话 ID / 日期键是**本地日期**
|
|
48
|
+
* (todayDate / formatDateKey),而 `createdAt` 是 **UTC ISO**——UTC+8 凌晨 00:00–08:00 创建的轮,
|
|
49
|
+
* 其 UTC 日期头仍是**前一天**,`createdAt.startsWith(本地日期)` 恒 false ⇒ 打捞不到,
|
|
50
|
+
* 该轮 24h 后被 GC 静默回收(用户视角:凌晨崩溃的那一轮无声消失)。
|
|
51
|
+
* 本函数是「本地日期 ↔ UTC 时间戳」换算判据的**单一真理源**:内核 `InMemoryRoundStore` 与
|
|
52
|
+
* 宿主 `WorkspaceRoundStore` 的打捞过滤共用它——两侧各自换算即造第二份判据,必漂移。
|
|
53
|
+
*
|
|
54
|
+
* 时区正确性:起止边界都从本地墙上时钟构造;end 用 `setDate(+1)` 日历进位而非 `+24h`
|
|
55
|
+
* (后者在 DST 切换日会偏移 1 小时)。任一参数不可解析时返回 false(NaN 比较恒 false,
|
|
56
|
+
* 与旧前缀匹配「非法输入即不中」的降级一致)。
|
|
57
|
+
*
|
|
58
|
+
* @param timestampIso UTC ISO 时间戳(如 `Round.createdAt`)
|
|
59
|
+
* @param localDate 本地日期键 YYYY-MM-DD(如会话 ID 的日期前缀)
|
|
60
|
+
* @returns 是否落在该本地日内(半开区间 `[start, end)`)
|
|
61
|
+
*/
|
|
62
|
+
export declare function isWithinLocalDay(timestampIso: string, localDate: string): boolean;
|
|
43
63
|
/**
|
|
44
64
|
* 组装会话标识:`date + "-" + session`
|
|
45
65
|
*
|
package/dist/utils/time.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,4DAA4D;AAC5D,eAAO,MAAM,UAAU,QAAsB,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKhD;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAQjF;AAeD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAInF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D"}
|
package/dist/utils/time.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 时间工具函数
|
|
3
3
|
*
|
|
4
|
-
* 从 messageHistory.ts
|
|
4
|
+
* 从 messageHistory.ts 提取的公共时间格式化函数。大部分仍为内核 `src/` 内部入口;
|
|
5
|
+
* `formatDateKey` / `todayDate` / `isWithinLocalDay` 经 `src/index.ts` 挂公开面供宿主复用
|
|
6
|
+
* (宿主消费前先过 publicApiSurfaceGuard 登记)。
|
|
5
7
|
*
|
|
6
|
-
* ⚠️
|
|
7
|
-
*
|
|
8
|
-
* 本文件只是内核内部的推荐入口,不是跨包单一真源。
|
|
8
|
+
* ⚠️ `nowIso` **未**进 `src/index.ts` 公开导出面,宿主拿不到它
|
|
9
|
+
* (实测宿主 `nowIso` 引用 = 0),宿主侧取当前时间仍是各自内联。
|
|
9
10
|
*
|
|
10
11
|
* API 对齐(历史):formatDateKey(date) 曾与精灵宿主 shared/dateUtils.ts 语义一致(该宿主已移除),
|
|
11
12
|
* 用于格式化任意 Date 为 YYYY-MM-DD(本地时区)。
|
|
@@ -49,6 +50,33 @@ export function formatDateKey(date) {
|
|
|
49
50
|
export function todayDate() {
|
|
50
51
|
return formatDateKey(new Date());
|
|
51
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* 判定 UTC ISO 时间戳是否落在指定**本地日期**的一天内(本地日区间 `[D 00:00, D+1 00:00)` → UTC 比较)。
|
|
55
|
+
*
|
|
56
|
+
* 为什么不能按日期头前缀匹配(E2E-TZ-SALVAGE-1 血训):会话 ID / 日期键是**本地日期**
|
|
57
|
+
* (todayDate / formatDateKey),而 `createdAt` 是 **UTC ISO**——UTC+8 凌晨 00:00–08:00 创建的轮,
|
|
58
|
+
* 其 UTC 日期头仍是**前一天**,`createdAt.startsWith(本地日期)` 恒 false ⇒ 打捞不到,
|
|
59
|
+
* 该轮 24h 后被 GC 静默回收(用户视角:凌晨崩溃的那一轮无声消失)。
|
|
60
|
+
* 本函数是「本地日期 ↔ UTC 时间戳」换算判据的**单一真理源**:内核 `InMemoryRoundStore` 与
|
|
61
|
+
* 宿主 `WorkspaceRoundStore` 的打捞过滤共用它——两侧各自换算即造第二份判据,必漂移。
|
|
62
|
+
*
|
|
63
|
+
* 时区正确性:起止边界都从本地墙上时钟构造;end 用 `setDate(+1)` 日历进位而非 `+24h`
|
|
64
|
+
* (后者在 DST 切换日会偏移 1 小时)。任一参数不可解析时返回 false(NaN 比较恒 false,
|
|
65
|
+
* 与旧前缀匹配「非法输入即不中」的降级一致)。
|
|
66
|
+
*
|
|
67
|
+
* @param timestampIso UTC ISO 时间戳(如 `Round.createdAt`)
|
|
68
|
+
* @param localDate 本地日期键 YYYY-MM-DD(如会话 ID 的日期前缀)
|
|
69
|
+
* @returns 是否落在该本地日内(半开区间 `[start, end)`)
|
|
70
|
+
*/
|
|
71
|
+
export function isWithinLocalDay(timestampIso, localDate) {
|
|
72
|
+
// 本地日起点:date-time 形态(带 T 与秒)按 ES 规范解析为**本地**时区
|
|
73
|
+
const start = new Date(`${localDate}T00:00:00`);
|
|
74
|
+
// 日终点:日历进位 +1 天(跨 DST 亦准;非法输入时 start/end 为 Invalid Date → NaN 比较恒 false)
|
|
75
|
+
const end = new Date(start);
|
|
76
|
+
end.setDate(end.getDate() + 1);
|
|
77
|
+
const t = Date.parse(timestampIso);
|
|
78
|
+
return t >= start.getTime() && t < end.getTime();
|
|
79
|
+
}
|
|
52
80
|
// ── 会话标识格式契约(SSOT 单一真理源)────────────────────
|
|
53
81
|
// sessionId 统一格式:`${date}-${session}`,date 固定 YYYY-MM-DD(10 位)。
|
|
54
82
|
// session 名允许含连字符(如分叉产生的 main-b1),故拆解必须按「前 10 位日期」切、
|
package/dist/utils/time.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB,EAAE,SAAiB;IACtE,+CAA+C;IAC/C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,SAAS,WAAW,CAAC,CAAC;IAChD,yEAAyE;IACzE,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;AACnD,CAAC;AAED,8CAA8C;AAC9C,gEAAgE;AAChE,qDAAqD;AACrD,iEAAiE;AACjE,uDAAuD;AACvD,sDAAsD;AACtD,EAAE;AACF,wBAAwB;AACxB,qDAAqD;AACrD,oEAAoE;AACpE,0CAA0C;AAC1C,4BAA4B;AAE5B;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAe;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO,4BAA4B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -323,13 +323,17 @@ agent.on('memoryAdded', (e) => console.log(`新记忆: ${e.source}:${e.name}`));
|
|
|
323
323
|
|
|
324
324
|
## 三、对话 API
|
|
325
325
|
|
|
326
|
-
### 3.1 `chat(input, signal?)` — 流式对话(唯一入口)
|
|
326
|
+
### 3.1 `chat(input, signal?, attachments?)` — 流式对话(唯一入口)
|
|
327
327
|
|
|
328
328
|
```typescript
|
|
329
|
-
async *chat(
|
|
329
|
+
async *chat(
|
|
330
|
+
input: string,
|
|
331
|
+
signal?: AbortSignal,
|
|
332
|
+
attachments?: readonly ImageRef[],
|
|
333
|
+
): AsyncGenerator<AgentChunk, void, unknown>
|
|
330
334
|
```
|
|
331
335
|
|
|
332
|
-
流式返回 `AgentChunk` 事件,可选传入 `signal`
|
|
336
|
+
流式返回 `AgentChunk` 事件,可选传入 `signal` 支持取消。可选 `attachments`(图片附件,5.2.0 起)为多模态输入入口:仅流式 `chat()` 承载(`chatSync` 不收图);要求当前模型声明 `supportsVision`,未声明时明确拒绝(不静默);不传时行为与签名升级前完全一致。见 §十六 `ImageRef` / `ImageResolver` / `imageTokens`。
|
|
333
337
|
|
|
334
338
|
```typescript
|
|
335
339
|
type AgentChunk =
|
|
@@ -602,6 +606,7 @@ interface ISessionStore {
|
|
|
602
606
|
| 方法 | 用途 |
|
|
603
607
|
|------|------|
|
|
604
608
|
| `forkSession(targetSession?)` → `AgentForkResult` | 分叉当前会话(同步,复制完整消息历史到新分支) |
|
|
609
|
+
| `currentRoundId()` → `string` | 当前在途轮次 id(`''` = 无在途轮)。用途:ask 挂起时 `TurnState.waiting` 投影**不含** roundId,宿主停止收场需据此给中断轮做归属(折叠区 / 容器底栏时间与复制 / 分叉锚点)。与内核 loop 层的当前轮 id 同源同值(单点委托,不缓存副本) |
|
|
605
610
|
|
|
606
611
|
### 6.2 多项目怎么办(形态定案)
|
|
607
612
|
|
|
@@ -1027,7 +1032,7 @@ Agent 不再管理 Provider 映射表,宿主自行管理。
|
|
|
1027
1032
|
| 分组 | 方法 |
|
|
1028
1033
|
|------|------|
|
|
1029
1034
|
| 生命周期 | `init()` / `close()` |
|
|
1030
|
-
| 对话 | `chat(input, signal?)` / `chatSync(input, signal?)` / `resumeExecution()` |
|
|
1035
|
+
| 对话 | `chat(input, signal?, attachments?)` / `chatSync(input, signal?)` / `resumeExecution()` |
|
|
1031
1036
|
| 事件 | `on()` / `off()` / `once()`(继承自 TypedEventEmitter) |
|
|
1032
1037
|
| 暂停/继续 | `pause(reason, source?)` / `resume()` / `requestPause(reason, source?)` / `cancelPauseRequest()` / `isPausePending()` / `interject(content)` / `removePendingInterject(index)` / `clearPendingInterjections()` / `getPendingInterjections()` / `discardCurrentCheckpoint()` |
|
|
1033
1038
|
| 会话 | `forkSession(targetSession?)` / `createCheckpoint()` / `getCheckpoint()` |
|
|
@@ -1297,6 +1302,11 @@ export { createProviderFromConfig } from '@zooique/memora';
|
|
|
1297
1302
|
export type { ProviderConfig } from '@zooique/memora';
|
|
1298
1303
|
export type { LlmProvider, ChatOptions } from '@zooique/memora';
|
|
1299
1304
|
export type { LlmChunk } from '@zooique/memora';
|
|
1305
|
+
// 图片输入(宿主注入解析器 + 视觉能力位;内核不直连外部存储与网络)
|
|
1306
|
+
export type { ImageRef, ImageResolver } from '@zooique/memora';
|
|
1307
|
+
// 单图折算成多少个令牌(方案五点九节的公式,对外只此一份);
|
|
1308
|
+
// 宿主在还没拼出完整文件信息、只拿到宽高时也能算,避免各侧重写该公式。
|
|
1309
|
+
export { imageTokens } from '@zooique/memora';
|
|
1300
1310
|
|
|
1301
1311
|
// 配置
|
|
1302
1312
|
export { loadConfig } from '@zooique/memora';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Memora · 接入指南
|
|
1
|
+
# Memora · 接入指南
|
|
2
2
|
|
|
3
3
|
> 帮助宿主项目开发者快速理解 Memora 的设计理念和接入方法。
|
|
4
4
|
>
|
|
5
|
-
>
|
|
5
|
+
> **本文档对应的内核版本**:即你安装的包版本(以包内 `package.json` 的 `version` 为准)。**刻意不在此写死版本号**——本文件随包发布,写死即会与包版本脱钩(无闸门能保证二者同步,故不陈述值就无从腐化)。各版完整变更见 [CHANGELOG](../CHANGELOG.md)。
|
|
6
6
|
>
|
|
7
7
|
> **最新已发布版本**:以 npm registry 为准(`npm view @zooique/memora dist-tags.latest`),不在包内复述。
|
|
8
8
|
>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
**内核零越界。** 核心库模块不直接调用 `console.*`(唯一日志出口为 `logging/` 单例,默认实现写 stderr)、不读 `process.stdin`、不管理 API Key、不写用户配置文件。
|
|
42
42
|
|
|
43
|
-
**Manager 委托模式。** Agent 面类只做编排,领域操作委托给专职 Manager:`agent.rolePack`(角色包)/ `agent.tools`(工具)/ `agent.skills`(技能)/ `agent.memory`(记忆查询+写入)/ `agent.works`(作品投影)/ `agent.polish`(文本润色)共 6 个业务 Manager(另有 `
|
|
43
|
+
**Manager 委托模式。** Agent 面类只做编排,领域操作委托给专职 Manager:`agent.rolePack`(角色包)/ `agent.tools`(工具)/ `agent.skills`(技能)/ `agent.memory`(记忆查询+写入)/ `agent.works`(作品投影)/ `agent.polish`(文本润色)共 6 个业务 Manager(另有 `security` / `sessionManager` / `agentHistory` / `rolePackManager` 等)。
|
|
44
44
|
|
|
45
45
|
```
|
|
46
46
|
┌────────────────────────────────────────────────────────────┐
|
|
@@ -90,6 +90,8 @@
|
|
|
90
90
|
npm install @zooique/memora
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
> **运行时要求**:Node.js ≥ 22.0.0(与 `package.json#engines` 同口径)。其中 SQLite 落盘工厂 `createNodeSqliteStorage`(`node:sqlite`)需 **Node ≥ 22.13**——22.13 起 `node:sqlite` 才免 `--experimental-sqlite` 标志。低于 22.13 时包可正常加载、内存存储照常可用,仅调用该工厂会抛出明确的「需 Node ≥22.13」专属错误(`ToolErrorCode.NOT_AVAILABLE`),不会静默失败。
|
|
94
|
+
|
|
93
95
|
### 2. 创建 Provider + Agent
|
|
94
96
|
|
|
95
97
|
```typescript
|
|
@@ -329,20 +331,46 @@ Memora 通过 `ISessionStore` 接口支持会话消息的持久化。宿主实
|
|
|
329
331
|
> **检查点持久化已退役(2026-09-10 减法)**:`saveCheckpoint` / `loadCheckpoint` / `deleteCheckpoint` 已从接口删除;跨重启恢复链整体下线,中止/断电一律把未完成 turn 补全为完整 turn 身份并在下次会话按历史加载,运行时暂停是同 turn 内续跑(内存态)。
|
|
330
332
|
|
|
331
333
|
```typescript
|
|
332
|
-
import type { ISessionStore, SessionMessage } from '@zooique/memora';
|
|
334
|
+
import type { ISessionStore, SessionMessage, SessionMeta } from '@zooique/memora';
|
|
333
335
|
|
|
334
|
-
//
|
|
336
|
+
// 宿主实现接口:round-based 单一模式 —— 消息内容存 RoundStore,本接口只持「Round 指针 + 会话元数据」
|
|
337
|
+
// 以下为接口全集(11 个必需方法,照抄可编译通过);`setSessionTitle` 可选,未实现亦可
|
|
335
338
|
class FileSessionStore implements ISessionStore {
|
|
336
|
-
|
|
337
|
-
|
|
339
|
+
// ── 会话元数据 ──
|
|
340
|
+
getSessionMeta(sessionId: string): SessionMeta | undefined {
|
|
341
|
+
return undefined; // 读元数据;不存在返回 undefined
|
|
338
342
|
}
|
|
339
|
-
|
|
340
|
-
//
|
|
341
|
-
|
|
343
|
+
updateSessionMeta(sessionId: string, meta: Partial<SessionMeta>): void {
|
|
344
|
+
// 按 partial 合并写(内核对 sessionId 只做透传,不改写 key)
|
|
345
|
+
}
|
|
346
|
+
listSessionMetas(): SessionMeta[] {
|
|
347
|
+
return []; // 全量元数据(宿主自用;内核当前不主动调用)
|
|
342
348
|
}
|
|
343
349
|
listSessions(): string[] {
|
|
344
|
-
//
|
|
345
|
-
|
|
350
|
+
return []; // 会话 ID 列表
|
|
351
|
+
}
|
|
352
|
+
createSession(meta: SessionMeta): void {
|
|
353
|
+
// 建会话元数据(宿主自用;内核当前不主动调用)
|
|
354
|
+
}
|
|
355
|
+
deleteSession(sessionId: string): void {
|
|
356
|
+
// 删会话元数据(宿主自用;内核当前不主动调用)。契约:删除后 getSessionMeta 应为 undefined
|
|
357
|
+
}
|
|
358
|
+
// ── Round 指针(消息内容不在此,归 RoundStore)──
|
|
359
|
+
appendRoundId(sessionId: string, roundId: string): void {
|
|
360
|
+
// 追加单个 Round 指针
|
|
361
|
+
}
|
|
362
|
+
appendRoundIds(sessionId: string, roundIds: string[]): void {
|
|
363
|
+
// 批量追加(批量语义由宿主定义去重/顺序)
|
|
364
|
+
}
|
|
365
|
+
getRoundIds(sessionId: string): string[] {
|
|
366
|
+
return []; // 内核据此把 Round 展开成对话历史
|
|
367
|
+
}
|
|
368
|
+
setRoundIds(sessionId: string, roundIds: string[]): void {
|
|
369
|
+
// 整体覆盖(用于修剪/重排)
|
|
370
|
+
}
|
|
371
|
+
// ── 消息读取 ──
|
|
372
|
+
loadMessages(date: string, session: string): SessionMessage[] {
|
|
373
|
+
return []; // 按「日期 + 会话」读消息(兼容旧存储形态;round-based 下内容由 RoundStore 提供)
|
|
346
374
|
}
|
|
347
375
|
}
|
|
348
376
|
|
|
@@ -354,10 +382,10 @@ const agent = new Agent({
|
|
|
354
382
|
```
|
|
355
383
|
|
|
356
384
|
**会话持久化特性:**
|
|
357
|
-
-
|
|
358
|
-
-
|
|
359
|
-
-
|
|
360
|
-
- `SessionMessage.role` 支持 `'user' | 'assistant' | 'system'
|
|
385
|
+
- **round-based 单一模式**:消息内容只存 `IRoundStore`,`ISessionStore` 只持 Round 指针 + 会话元数据;两者必须**同源单例**(见 十.6 存储单例约束),双实例会互相覆盖。
|
|
386
|
+
- 日期使用 `todayDate()` 动态获取,确保跨日后消息写入当天目录。
|
|
387
|
+
- 内核真实调用的方法 = `loadMessages` / `listSessions` / `getSessionMeta` / `updateSessionMeta` / `appendRoundId` / `getRoundIds` / `setRoundIds`;`createSession` / `deleteSession` / `listSessionMetas` 是**契约方法**(宿主自管理与实现完整性所需),**内核当前不主动调用**。
|
|
388
|
+
- `SessionMessage.role` 支持 `'user' | 'assistant' | 'system'`。
|
|
361
389
|
|
|
362
390
|
---
|
|
363
391
|
|
|
@@ -642,7 +670,7 @@ for (const chapter of chapters) {
|
|
|
642
670
|
|
|
643
671
|
**前提:存储方案由宿主自选,内核只定契约。** 内核只定义 `IMemoryStorage` / `ISessionStore` 接口,**不规定后端**——SQLite、JSON 文件、内存实现一视同仁,任何后端都不得被写进内核逻辑(5.0.0 起内核**提供**可选的 SQLite 实现 `createNodeSqliteStorage`,但那是「多一个可选实现」,**不是**把后端写进逻辑——选哪个仍归宿主,`Agent` 构造契约不变)。接口方法为**同步语义**(对齐 better-sqlite3),异步后端需另行扩展接口;JSON 落地实现在同步路径上做全量重写,记忆量增长时由宿主自行评估更优后端(阈值与权衡见 `storageInterface.ts` 头注释)。第一宿主 memora-vscode 当前用 JSON 文件,换成 SQLite **不需要改内核**。
|
|
644
672
|
|
|
645
|
-
1.
|
|
673
|
+
1. **必填三项:`projectPath` / `provider` / `dataDir`** — 三者均无缺省值,缺一即无法构造(`AgentOptions` 中这三个字段**不带 `?`**,其余全部可选)。`projectPath` 决定项目级配置与锁的锚点,`provider` 是前台 LLM 调用入口,`dataDir` 是 Agent 级资源目录。**`storage` 缺省为内置内存实现**(对话与记忆闭环照常,仅不持久化)⇒ 想落盘直接用 `createNodeSqliteStorage`,**无需自实现存储接口**。
|
|
646
674
|
2. **configDir** 指向 Agent 级配置目录,所有项目共享
|
|
647
675
|
3. **项目级 `.memora/`** 放项目级配置(`rules/`、`skills/`)与内核写入的项目锁 `.lock`;`dataDir` 若指向此处(第一宿主 memora-vscode 即如此),记忆库与会话也落在这里
|
|
648
676
|
4. **角色包只能手动切换**(`agent.switchRolePack(name)` / `agent.rolePack.activate(name)`)——无输入自动匹配、无粘性锁存、无互斥触发;已激活的角色包在当前会话内保持固定(v0.13 已移除自动匹配全链)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zooique/memora",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Node.js 专用 Agent 架构 — 本地、私有、领域无关,摘要即记忆(memory-as-summary;零第三方运行时依赖,依赖 Node.js 内置模块)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,14 +44,17 @@
|
|
|
44
44
|
"build:clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && npm run build",
|
|
45
45
|
"test": "vitest run",
|
|
46
46
|
"test:watch": "vitest",
|
|
47
|
-
"test:cov": "vitest run --coverage",
|
|
47
|
+
"test:cov": "node scripts/verify-node-pin.mjs && vitest run --coverage",
|
|
48
48
|
"test:all": "npm run test && npm run test --prefix hosts/memora-vscode",
|
|
49
49
|
"lint": "eslint . --max-warnings 0",
|
|
50
50
|
"lint:fix": "eslint . --fix",
|
|
51
51
|
"ci:local": "node scripts/local-ci.mjs",
|
|
52
52
|
"verify:dist-contract": "node scripts/verify-dist-contract.mjs",
|
|
53
|
+
"verify:toolchain": "node scripts/verify-toolchain-pin.mjs",
|
|
53
54
|
"verify:changelog": "node scripts/verify-changelog-version.mjs",
|
|
54
55
|
"verify:publish-docs": "node scripts/verify-publish-docs.mjs",
|
|
56
|
+
"verify:ledger-hygiene": "node scripts/verify-ledger-hygiene.mjs",
|
|
57
|
+
"verify:ledger-fold": "node scripts/verify-ledger-fold.mjs",
|
|
55
58
|
"format": "prettier --write \"**/*.{ts,mjs,md,json}\"",
|
|
56
59
|
"format:check": "prettier --check \"**/*.{ts,mjs,md,json}\"",
|
|
57
60
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.scripts.json",
|