acp-ts 1.0.6 → 1.0.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.
package/dist/agentcp.d.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import { IAgentCP, IAgentIdentity } from "./interfaces";
2
+ import { MessageStore } from "./messagestore";
2
3
  declare class AgentCP implements IAgentCP {
3
4
  private seedPassword;
4
5
  private apUrl;
5
6
  private msgUrl;
6
7
  private activeAid;
8
+ private _messageStore;
7
9
  private agentMdPath;
8
- constructor(apiUrl: string, seedPassword?: string);
10
+ private agentMdUploaded;
11
+ get messageStore(): MessageStore;
12
+ constructor(apiUrl: string, seedPassword?: string, basePath?: string, options?: {
13
+ persistMessages?: boolean;
14
+ });
9
15
  /**
10
16
  * 初始化并预热加密模块
11
17
  */
@@ -21,28 +27,14 @@ declare class AgentCP implements IAgentCP {
21
27
  messageServer: string;
22
28
  heartbeatServer: string;
23
29
  }>;
24
- /**
25
- * 设置 agent.md 文件路径,登录成功后会自动上传(仅首次)
26
- * @param filePath agent.md 文件的本地路径
27
- */
28
- setAgentMdPath(filePath: string): void;
29
- /**
30
- * 重置 agent.md 上传状态,下次登录时会重新上传
31
- * 当 agent.md 内容更新后调用此方法
32
- */
33
- resetAgentMdUploadStatus(): Promise<void>;
34
- /**
35
- * 上传 agent.md 文件
36
- * @param signature 签名(从 signIn 获取)
37
- * @returns 上传结果
38
- */
39
- private uploadAgentMd;
40
30
  getCertInfo(aid: string): Promise<{
41
31
  privateKey: string;
42
32
  publicKey: string;
43
33
  csr: string;
44
34
  cert: string;
45
35
  } | null>;
36
+ setAgentMdPath(filePath: string): void;
37
+ resetAgentMdUploadStatus(): Promise<void>;
46
38
  private handleError;
47
39
  }
48
40
  export { AgentCP };
package/dist/agentcp.js CHANGED
@@ -1,32 +1,38 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.AgentCP = void 0;
7
4
  const cert_1 = require("./cert");
8
5
  const datamanager_1 = require("./datamanager");
9
6
  const api_1 = require("./api");
10
7
  const utils_1 = require("./utils");
11
- const axios_1 = __importDefault(require("axios"));
12
- // 环境检测
13
- const isNodeEnvironment = typeof process !== 'undefined' &&
14
- process.versions != null &&
15
- process.versions.node != null;
8
+ const messagestore_1 = require("./messagestore");
9
+ const filesync_1 = require("./filesync");
16
10
  class AgentCP {
17
- constructor(apiUrl, seedPassword = "") {
11
+ get messageStore() {
12
+ return this._messageStore;
13
+ }
14
+ constructor(apiUrl, seedPassword = "", basePath, options) {
15
+ var _a;
18
16
  this.activeAid = '';
19
- this.agentMdPath = '';
17
+ this.agentMdPath = null;
18
+ this.agentMdUploaded = false;
20
19
  if (!apiUrl) {
21
20
  this.handleError("参数缺失:apiUrl不应为空");
22
21
  }
23
22
  if (apiUrl.startsWith('http://')) {
24
23
  this.handleError("apiUrl不需要http://开头");
25
24
  }
25
+ if (basePath) {
26
+ datamanager_1.CertAndKeyStore.setBasePath(basePath);
27
+ }
26
28
  const baseUrl = `https://acp3.${apiUrl}`;
27
29
  this.seedPassword = seedPassword;
28
30
  this.apUrl = `${baseUrl}/api/accesspoint`;
29
31
  this.msgUrl = `${baseUrl}/api/message`;
32
+ this._messageStore = new messagestore_1.MessageStore({
33
+ persistMessages: (_a = options === null || options === void 0 ? void 0 : options.persistMessages) !== null && _a !== void 0 ? _a : false,
34
+ basePath: basePath || process.cwd(),
35
+ });
30
36
  // 预热加密模块
31
37
  this.initializeCrypto();
32
38
  }
@@ -155,20 +161,25 @@ class AgentCP {
155
161
  else {
156
162
  messageSignature = (_a = msgData.signature) !== null && _a !== void 0 ? _a : '';
157
163
  }
158
- // 登录成功后自动上传 agent.md(如果已配置路径且未上传过)
159
- if (this.agentMdPath && messageSignature) {
160
- const uploaded = await datamanager_1.CertAndKeyStore.getData(`agent_md_uploaded_${aid}`);
161
- if (!uploaded) {
162
- const uploadResult = await this.uploadAgentMd(messageSignature);
163
- if (uploadResult.success) {
164
- console.log(`agent.md 上传成功: ${uploadResult.url}`);
165
- // 记录已上传状态
166
- await datamanager_1.CertAndKeyStore.storeData(`agent_md_uploaded_${aid}`, true);
164
+ // 登录成功后自动上传 agent.md(仅首次)
165
+ if (this.agentMdPath && !this.agentMdUploaded) {
166
+ try {
167
+ const fileSync = new filesync_1.FileSync({
168
+ apiUrl: this.msgUrl,
169
+ aid: this.activeAid,
170
+ signature: messageSignature,
171
+ });
172
+ const result = await fileSync.uploadAgentMdFromFile(this.agentMdPath);
173
+ if (result.success) {
174
+ this.agentMdUploaded = true;
167
175
  }
168
176
  else {
169
- console.warn(`agent.md 上传失败: ${uploadResult.error}`);
177
+ console.warn('agent.md 上传失败:', result.error);
170
178
  }
171
179
  }
180
+ catch (err) {
181
+ console.warn('agent.md 上传异常:', err);
182
+ }
172
183
  }
173
184
  return {
174
185
  messageSignature,
@@ -176,63 +187,6 @@ class AgentCP {
176
187
  heartbeatServer
177
188
  };
178
189
  }
179
- /**
180
- * 设置 agent.md 文件路径,登录成功后会自动上传(仅首次)
181
- * @param filePath agent.md 文件的本地路径
182
- */
183
- setAgentMdPath(filePath) {
184
- this.agentMdPath = filePath;
185
- }
186
- /**
187
- * 重置 agent.md 上传状态,下次登录时会重新上传
188
- * 当 agent.md 内容更新后调用此方法
189
- */
190
- async resetAgentMdUploadStatus() {
191
- if (this.activeAid) {
192
- await datamanager_1.CertAndKeyStore.storeData(`agent_md_uploaded_${this.activeAid}`, false);
193
- }
194
- }
195
- /**
196
- * 上传 agent.md 文件
197
- * @param signature 签名(从 signIn 获取)
198
- * @returns 上传结果
199
- */
200
- async uploadAgentMd(signature) {
201
- var _a, _b, _c;
202
- if (!this.agentMdPath) {
203
- return { success: false, error: '未设置 agent.md 路径' };
204
- }
205
- if (!isNodeEnvironment) {
206
- return { success: false, error: '自动上传 agent.md 仅支持 Node.js 环境' };
207
- }
208
- const fs = require('fs');
209
- try {
210
- if (!fs.existsSync(this.agentMdPath)) {
211
- return { success: false, error: `文件不存在: ${this.agentMdPath}` };
212
- }
213
- const content = fs.readFileSync(this.agentMdPath, 'utf8');
214
- // 检查文件大小限制(4KB)
215
- const contentSize = Buffer.byteLength(content, 'utf8');
216
- if (contentSize > 4 * 1024) {
217
- return { success: false, error: `文件大小超过限制: ${contentSize} bytes > 4KB` };
218
- }
219
- const url = `https://${this.activeAid}/agent.md`;
220
- const response = await axios_1.default.post(url, content, {
221
- headers: {
222
- 'Content-Type': 'text/markdown',
223
- 'Authorization': `Bearer ${signature}`
224
- }
225
- });
226
- if (response.status === 200) {
227
- return { success: true, url: response.data.url || url };
228
- }
229
- return { success: false, error: ((_a = response.data) === null || _a === void 0 ? void 0 : _a.message) || `上传失败: ${response.status}` };
230
- }
231
- catch (error) {
232
- const errorMsg = ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) || error.message || '上传 agent.md 失败';
233
- return { success: false, error: errorMsg };
234
- }
235
- }
236
190
  async getCertInfo(aid) {
237
191
  const csr = await datamanager_1.CertAndKeyStore.getCsr(aid);
238
192
  const privateKey = await datamanager_1.CertAndKeyStore.getPrivateKey(aid);
@@ -247,6 +201,12 @@ class AgentCP {
247
201
  cert: certPem
248
202
  };
249
203
  }
204
+ setAgentMdPath(filePath) {
205
+ this.agentMdPath = filePath;
206
+ }
207
+ async resetAgentMdUploadStatus() {
208
+ this.agentMdUploaded = false;
209
+ }
250
210
  handleError(error, customMessage) {
251
211
  const errorMessage = error instanceof Error ? error.message : String(error);
252
212
  throw new Error(`${customMessage || '操作失败'}: ${errorMessage}`);
@@ -1,37 +1,15 @@
1
1
  import { IAgentCP, IAgentWS, IConnectionConfig } from './interfaces';
2
- import { FileSync, SyncResult } from './filesync';
3
2
  declare class AgentManager {
4
3
  private static instance;
5
4
  private agentCP;
6
5
  private agentWS;
7
- private fileSync;
8
- private apiUrl;
9
6
  private constructor();
10
7
  static getInstance(): AgentManager;
11
- initACP(apiUrl: string, seedPassword?: string): IAgentCP;
8
+ initACP(apiUrl: string, seedPassword?: string, basePath?: string, options?: {
9
+ persistMessages?: boolean;
10
+ }): IAgentCP;
12
11
  initAWS(aid: string, config: IConnectionConfig): IAgentWS;
13
12
  acp(): IAgentCP;
14
13
  aws(): IAgentWS;
15
- /**
16
- * 初始化文件同步模块
17
- * @param aid 智能体ID
18
- * @param signature 签名
19
- * @param localDir 本地公共文件目录
20
- * @returns FileSync实例
21
- */
22
- initFileSync(aid: string, signature: string, localDir: string): FileSync;
23
- /**
24
- * 获取文件同步实例
25
- * @returns FileSync实例
26
- */
27
- fs(): FileSync;
28
- /**
29
- * 快捷方法:同步公共文件
30
- * @param aid 智能体ID
31
- * @param signature 签名
32
- * @param localDir 本地公共文件目录
33
- * @returns 同步结果
34
- */
35
- syncPublicFiles(aid: string, signature: string, localDir: string): Promise<SyncResult>;
36
14
  }
37
15
  export { AgentManager };
@@ -3,13 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AgentManager = void 0;
4
4
  const agentcp_1 = require("./agentcp");
5
5
  const agentws_1 = require("./agentws");
6
- const filesync_1 = require("./filesync");
7
6
  class AgentManager {
8
7
  constructor() {
9
8
  this.agentCP = null;
10
9
  this.agentWS = null;
11
- this.fileSync = null;
12
- this.apiUrl = '';
13
10
  }
14
11
  static getInstance() {
15
12
  if (!AgentManager.instance) {
@@ -17,10 +14,10 @@ class AgentManager {
17
14
  }
18
15
  return AgentManager.instance;
19
16
  }
20
- initACP(apiUrl, seedPassword = "") {
21
- this.apiUrl = apiUrl;
22
- this.agentCP = new agentcp_1.AgentCP(apiUrl, seedPassword);
23
- return this.agentCP;
17
+ initACP(apiUrl, seedPassword = "", basePath, options) {
18
+ const acp = new agentcp_1.AgentCP(apiUrl, seedPassword, basePath, options);
19
+ this.agentCP = acp;
20
+ return acp;
24
21
  }
25
22
  initAWS(aid, config) {
26
23
  const { messageServer, messageSignature } = config;
@@ -39,48 +36,5 @@ class AgentManager {
39
36
  }
40
37
  return this.agentWS;
41
38
  }
42
- /**
43
- * 初始化文件同步模块
44
- * @param aid 智能体ID
45
- * @param signature 签名
46
- * @param localDir 本地公共文件目录
47
- * @returns FileSync实例
48
- */
49
- initFileSync(aid, signature, localDir) {
50
- if (!this.apiUrl) {
51
- throw new Error("请先调用initACP初始化API地址");
52
- }
53
- // 构建完整的 API URL(与 AgentCP 保持一致)
54
- const baseUrl = `https://acp3.${this.apiUrl}`;
55
- const config = {
56
- apiUrl: `${baseUrl}/api/accesspoint`,
57
- aid: aid,
58
- signature: signature,
59
- localDir: localDir
60
- };
61
- this.fileSync = new filesync_1.FileSync(config);
62
- return this.fileSync;
63
- }
64
- /**
65
- * 获取文件同步实例
66
- * @returns FileSync实例
67
- */
68
- fs() {
69
- if (!this.fileSync) {
70
- throw new Error("FileSync未初始化,请先调用initFileSync");
71
- }
72
- return this.fileSync;
73
- }
74
- /**
75
- * 快捷方法:同步公共文件
76
- * @param aid 智能体ID
77
- * @param signature 签名
78
- * @param localDir 本地公共文件目录
79
- * @returns 同步结果
80
- */
81
- async syncPublicFiles(aid, signature, localDir) {
82
- const fileSync = this.initFileSync(aid, signature, localDir);
83
- return fileSync.syncPublicFiles();
84
- }
85
39
  }
86
40
  exports.AgentManager = AgentManager;
package/dist/cli.js CHANGED
@@ -107,6 +107,7 @@ function update() {
107
107
  const args = process.argv.slice(2);
108
108
  let port = 9527; // 使用非常用端口
109
109
  let apiUrl = 'aid.pub'; // 默认服务地址
110
+ let dataDir = ''; // 数据目录
110
111
  // 解析命令行参数
111
112
  for (let i = 0; i < args.length; i++) {
112
113
  if (args[i] === 'update') {
@@ -140,6 +141,15 @@ for (let i = 0; i < args.length; i++) {
140
141
  apiUrl = urlArg;
141
142
  i++;
142
143
  }
144
+ else if (args[i] === '-d' || args[i] === '--data-dir') {
145
+ const dirArg = args[i + 1];
146
+ if (!dirArg || dirArg.startsWith('-')) {
147
+ console.error('错误: -d 参数需要指定数据目录路径');
148
+ process.exit(1);
149
+ }
150
+ dataDir = dirArg;
151
+ i++;
152
+ }
143
153
  else if (args[i] === '-h' || args[i] === '--help') {
144
154
  console.log(`
145
155
  acp-ts - 智能体通信调试工具 v${getVersion()}
@@ -152,6 +162,7 @@ acp-ts - 智能体通信调试工具 v${getVersion()}
152
162
  -v, --version 显示版本号
153
163
  -p, --port <端口> 指定服务端口 (默认: 9527)
154
164
  -u, --url <地址> 指定 API 服务器地址 (默认: aid.pub)
165
+ -d, --data-dir <路径> 指定数据目录 (默认: 当前目录)
155
166
  -h, --help 显示帮助信息
156
167
 
157
168
  安装:
@@ -165,4 +176,4 @@ acp-ts - 智能体通信调试工具 v${getVersion()}
165
176
  process.exit(0);
166
177
  }
167
178
  }
168
- (0, server_1.startServer)(port, apiUrl);
179
+ (0, server_1.startServer)(port, apiUrl, dataDir);
@@ -1,5 +1,8 @@
1
1
  export declare class CertAndKeyStore {
2
2
  static aidKey: string;
3
+ private static basePath;
4
+ static setBasePath(p: string): void;
5
+ static getAIDsDir(): string;
3
6
  static storeData(key: string, value: any): Promise<void>;
4
7
  static getData(key: string): Promise<any>;
5
8
  static getGuestAid(): Promise<string | null>;
@@ -105,7 +105,13 @@ else {
105
105
  }
106
106
  }
107
107
  class CertAndKeyStore {
108
- // 存储数据
108
+ static setBasePath(p) {
109
+ this.basePath = p;
110
+ }
111
+ static getAIDsDir() {
112
+ return path.join(this.basePath, 'AIDs');
113
+ }
114
+ // 存储数据(仍用 storage.json,用于会话/消息)
109
115
  static async storeData(key, value) {
110
116
  try {
111
117
  await AsyncStorage.setItem(key, JSON.stringify(value));
@@ -114,7 +120,7 @@ class CertAndKeyStore {
114
120
  console.error(e);
115
121
  }
116
122
  }
117
- // 获取数据
123
+ // 获取数据(仍用 storage.json,用于会话/消息)
118
124
  static async getData(key) {
119
125
  try {
120
126
  const value = await AsyncStorage.getItem(key);
@@ -151,48 +157,82 @@ class CertAndKeyStore {
151
157
  }
152
158
  }
153
159
  static async getAids() {
154
- const aids = await this.getData(this.aidKey);
155
- if (aids) {
156
- return aids;
160
+ try {
161
+ const aidsDir = this.getAIDsDir();
162
+ if (!fs.existsSync(aidsDir)) {
163
+ return [];
164
+ }
165
+ const entries = fs.readdirSync(aidsDir, { withFileTypes: true });
166
+ return entries.filter(e => e.isDirectory()).map(e => e.name);
167
+ }
168
+ catch (e) {
169
+ console.error('扫描 AIDs 目录失败:', e);
170
+ return [];
157
171
  }
158
- return [];
159
172
  }
160
173
  static async saveAid(aid) {
161
174
  try {
162
- const aids = await this.getAids();
163
- if (aids) {
164
- if (!aids.includes(aid)) {
165
- const mergedAids = [...aids, aid];
166
- await this.storeData(this.aidKey, mergedAids);
167
- }
175
+ const privateDir = path.join(this.getAIDsDir(), aid, 'private');
176
+ const publicDir = path.join(this.getAIDsDir(), aid, 'public');
177
+ if (!fs.existsSync(privateDir)) {
178
+ fs.mkdirSync(privateDir, { recursive: true });
168
179
  }
169
- else {
170
- await this.storeData(this.aidKey, [aid]);
180
+ if (!fs.existsSync(publicDir)) {
181
+ fs.mkdirSync(publicDir, { recursive: true });
171
182
  }
172
183
  }
173
184
  catch (e) {
174
- console.error('保存数组失败:', e);
185
+ console.error('创建 AID 目录失败:', e);
175
186
  }
176
187
  }
177
188
  static async getCertificate(aid) {
178
- return this.getData(`cert_${aid}`);
189
+ try {
190
+ const certPath = path.join(this.getAIDsDir(), aid, 'public', `${aid}.crt`);
191
+ if (fs.existsSync(certPath)) {
192
+ return fs.readFileSync(certPath, 'utf-8');
193
+ }
194
+ return null;
195
+ }
196
+ catch (e) {
197
+ console.error('读取证书失败:', e);
198
+ return null;
199
+ }
179
200
  }
180
201
  static async saveCertificate(aid, cert) {
181
- await this.storeData(`cert_${aid}`, cert);
202
+ await this.saveAid(aid);
203
+ const certPath = path.join(this.getAIDsDir(), aid, 'public', `${aid}.crt`);
204
+ fs.writeFileSync(certPath, cert, 'utf-8');
182
205
  }
183
206
  static async getCsr(aid) {
184
- return this.getData(`csr_${aid}`);
207
+ try {
208
+ const csrPath = path.join(this.getAIDsDir(), aid, 'private', `${aid}.csr`);
209
+ if (fs.existsSync(csrPath)) {
210
+ return fs.readFileSync(csrPath, 'utf-8');
211
+ }
212
+ return null;
213
+ }
214
+ catch (e) {
215
+ console.error('读取 CSR 失败:', e);
216
+ return null;
217
+ }
185
218
  }
186
219
  static async saveCsr(aid, csr) {
187
- await this.storeData(`csr_${aid}`, csr);
220
+ await this.saveAid(aid);
221
+ const csrPath = path.join(this.getAIDsDir(), aid, 'private', `${aid}.csr`);
222
+ fs.writeFileSync(csrPath, csr, 'utf-8');
188
223
  }
189
224
  static async savePrivateKey(aid, key) {
190
- await this.storeData(`private_key_${aid}`, key);
225
+ await this.saveAid(aid);
226
+ const keyPath = path.join(this.getAIDsDir(), aid, 'private', `${aid}.key`);
227
+ fs.writeFileSync(keyPath, key, 'utf-8');
191
228
  }
192
229
  static async getPrivateKey(aid) {
193
230
  try {
194
- const encryptedKey = await this.getData(`private_key_${aid}`);
195
- return encryptedKey;
231
+ const keyPath = path.join(this.getAIDsDir(), aid, 'private', `${aid}.key`);
232
+ if (fs.existsSync(keyPath)) {
233
+ return fs.readFileSync(keyPath, 'utf-8');
234
+ }
235
+ return null;
196
236
  }
197
237
  catch (error) {
198
238
  console.error('获取私钥失败:', error);
@@ -202,3 +242,4 @@ class CertAndKeyStore {
202
242
  }
203
243
  exports.CertAndKeyStore = CertAndKeyStore;
204
244
  CertAndKeyStore.aidKey = 'currentAidKey';
245
+ CertAndKeyStore.basePath = process.cwd();
package/dist/index.d.ts CHANGED
@@ -2,6 +2,6 @@ import { ConnectionStatus } from "./websocket";
2
2
  import { AgentManager } from './agentmanager';
3
3
  import { IAgentIdentity } from './interfaces';
4
4
  import { HeartbeatClient, HeartbeatStatus, InviteInfo } from './heartbeat';
5
- import { FileSync, FileSyncStatus, LocalFileInfo, SyncResult, FileSyncConfig } from './filesync';
6
- export { AgentManager, IAgentIdentity, HeartbeatClient, FileSync };
7
- export type { ConnectionStatus, HeartbeatStatus, InviteInfo, FileSyncStatus, LocalFileInfo, SyncResult, FileSyncConfig, };
5
+ import { MessageStore, MessageItem, SessionRecord, Session, SessionSummary } from './messagestore';
6
+ export { AgentManager, IAgentIdentity, HeartbeatClient, MessageStore };
7
+ export type { ConnectionStatus, HeartbeatStatus, InviteInfo, MessageItem, SessionRecord, Session, SessionSummary, };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FileSync = exports.HeartbeatClient = exports.AgentManager = void 0;
3
+ exports.MessageStore = exports.HeartbeatClient = exports.AgentManager = void 0;
4
4
  const agentmanager_1 = require("./agentmanager");
5
5
  Object.defineProperty(exports, "AgentManager", { enumerable: true, get: function () { return agentmanager_1.AgentManager; } });
6
6
  const heartbeat_1 = require("./heartbeat");
7
7
  Object.defineProperty(exports, "HeartbeatClient", { enumerable: true, get: function () { return heartbeat_1.HeartbeatClient; } });
8
- const filesync_1 = require("./filesync");
9
- Object.defineProperty(exports, "FileSync", { enumerable: true, get: function () { return filesync_1.FileSync; } });
8
+ const messagestore_1 = require("./messagestore");
9
+ Object.defineProperty(exports, "MessageStore", { enumerable: true, get: function () { return messagestore_1.MessageStore; } });
@@ -1,4 +1,5 @@
1
1
  import { ACPMessageSessionResponse, ConnectionStatus, InviteStatus } from "./websocket";
2
+ import { MessageStore } from "./messagestore";
2
3
  /**
3
4
  * 代理身份信息接口
4
5
  * @interface IAgentIdentity
@@ -28,6 +29,10 @@ interface IConnectionConfig {
28
29
  * @interface IAgentCP
29
30
  */
30
31
  interface IAgentCP {
32
+ /**
33
+ * 消息存储模块
34
+ */
35
+ readonly messageStore: MessageStore;
31
36
  /**
32
37
  * 导入代理身份
33
38
  * @param {IAgentIdentity} identity - 代理身份信息
@@ -0,0 +1,65 @@
1
+ export type MessageItem = {
2
+ type: 'sent' | 'received';
3
+ content: string;
4
+ from?: string;
5
+ to?: string;
6
+ timestamp: number;
7
+ };
8
+ export interface SessionRecord {
9
+ sessionId: string;
10
+ identifyingCode: string;
11
+ peerAid: string;
12
+ ownerAid: string;
13
+ type: 'outgoing' | 'incoming';
14
+ createdAt: number;
15
+ lastMessageAt: number;
16
+ messageCount: number;
17
+ closed: boolean;
18
+ }
19
+ export interface Session extends SessionRecord {
20
+ messages: MessageItem[];
21
+ }
22
+ export interface SessionSummary {
23
+ sessionId: string;
24
+ peerAid: string;
25
+ ownerAid: string;
26
+ type: 'outgoing' | 'incoming';
27
+ lastMessageAt: number;
28
+ messageCount: number;
29
+ createdAt: number;
30
+ lastMessage: string;
31
+ closed: boolean;
32
+ }
33
+ export declare class MessageStore {
34
+ private persistMessages;
35
+ private basePath;
36
+ private maxMessagesPerSession;
37
+ private sessions;
38
+ constructor(options: {
39
+ persistMessages: boolean;
40
+ basePath: string;
41
+ maxMessagesPerSession?: number;
42
+ });
43
+ private getSessionsDir;
44
+ private getIndexPath;
45
+ private getSessionFilePath;
46
+ private ensureDir;
47
+ loadSessionsForAid(ownerAid: string): Promise<void>;
48
+ /** 从 JSONL 文件读取消息列表 */
49
+ private readMessagesFromFile;
50
+ private migrateFromLegacy;
51
+ getOrCreateSession(sessionId: string, identifyingCode: string, peerAid: string, type: 'outgoing' | 'incoming', ownerAid: string): Session;
52
+ addMessageToSession(sessionId: string, msg: MessageItem): void;
53
+ getSessionList(ownerAid: string): SessionSummary[];
54
+ hasSession(sessionId: string): boolean;
55
+ getSession(sessionId: string): Session | null;
56
+ /** 只写索引文件 */
57
+ flushIndex(ownerAid: string): Promise<void>;
58
+ /** 全量重写单个会话的消息文件(JSONL 格式) */
59
+ flushSession(ownerAid: string, sessionId: string): Promise<void>;
60
+ /** 追加单条消息到 JSONL 文件 */
61
+ private appendMessage;
62
+ /** 全量写入指定 AID 的索引 + 所有会话消息文件 */
63
+ flush(ownerAid: string): Promise<void>;
64
+ flushAll(): Promise<void>;
65
+ }