@ppagent/memory 0.1.1 → 0.1.2

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 (4) hide show
  1. package/dist/index.d.ts +159 -117
  2. package/dist/index.js +326 -157
  3. package/llms.txt +845 -0
  4. package/package.json +10 -8
package/dist/index.d.ts CHANGED
@@ -270,8 +270,10 @@ interface AddDocumentOptions {
270
270
  metadata?: Record<string, unknown>;
271
271
  /** 默认取 config.buildGraphDefault(默认 "auto")*/
272
272
  buildGraph?: BuildGraphMode;
273
- /** 默认 false:document 落库即返回;true 则等切块/图谱全部完成 */
273
+ /** 默认 false:document 落库即返回;true 则等切块落库,文档可检索 */
274
274
  wait?: boolean;
275
+ /** 默认 false:true 时在 wait 的基础上额外等待知识图谱构建完成 */
276
+ waitGraph?: boolean;
275
277
  }
276
278
  interface KnowledgeSearchOptions {
277
279
  query: string;
@@ -312,12 +314,14 @@ interface MemoryConfig {
312
314
  llmBaseUrl: string;
313
315
  llmApiKey: string;
314
316
  llmModel: string;
315
- /** LLM / embedding HTTP 请求超时(毫秒,默认 30000)。超时即中止并按重试策略处理。*/
317
+ /** LLM / embedding HTTP 请求超时(毫秒,默认 60000)。超时即中止并按重试策略处理。*/
316
318
  httpTimeoutMs?: number;
317
319
  /** LLM / embedding 请求失败(网络错误/超时/5xx/429)时的最大重试次数(默认 2,即最多请求 3 次)。*/
318
320
  httpMaxRetries?: number;
319
321
  /** embedding 单次请求最多包含的文本条数,超出自动分批(默认 20)。*/
320
322
  embeddingBatchSize?: number;
323
+ /** embedding 批次并发数(默认 2)。*/
324
+ embeddingConcurrency?: number;
321
325
  sessionTokenLimit?: number;
322
326
  historyWindowTokenLimit?: number;
323
327
  topicRatio?: [number, number, number];
@@ -358,10 +362,156 @@ interface MemoryConfig {
358
362
  knowledgeGraphAnchorTopK?: number;
359
363
  /** 每个锚点实体一跳扩展的最大关系数(默认 10)*/
360
364
  knowledgeGraphHopLimit?: number;
365
+ /** 文档图谱构建时并发抽取片段数(默认 2)*/
366
+ graphExtractConcurrency?: number;
367
+ /** waitGraph=true 时等待图谱构建的整体超时(毫秒,默认 120000)*/
368
+ graphBuildTimeoutMs?: number;
369
+ /**
370
+ * init 完成后是否后台执行一次存储压实(碎片合并 + 历史版本清理,默认 true)。
371
+ * 不阻塞启动;嵌入式单进程使用时建议保持开启,否则 LanceDB 版本目录会无限膨胀、启动越来越慢。
372
+ */
373
+ autoOptimizeOnInit?: boolean;
374
+ /** 压实时保留多久内的历史版本(毫秒,默认 0 即仅保留当前版本)。*/
375
+ optimizeVersionRetentionMs?: number;
376
+ /** 启动时恢复各会话历史窗口的并发数(默认 8,旧行为为逐会话串行)。*/
377
+ restoreConcurrency?: number;
361
378
  }
362
379
  interface ResolvedConfig extends Required<MemoryConfig> {
363
380
  }
364
381
 
382
+ /** 单表压实结果(compaction + 历史版本清理)*/
383
+ interface StorageOptimizeResult {
384
+ table: string;
385
+ fragmentsRemoved: number;
386
+ fragmentsAdded: number;
387
+ filesRemoved: number;
388
+ oldVersionsRemoved: number;
389
+ bytesRemoved: number;
390
+ }
391
+ declare class LanceService {
392
+ private readonly config;
393
+ private conn;
394
+ private messagesTable;
395
+ private topicsTable;
396
+ private factsTable;
397
+ private sessionsTable;
398
+ private documentsTable;
399
+ private chunksTable;
400
+ private isNewMessagesTable;
401
+ private isNewTopicsTable;
402
+ private isNewSessionsTable;
403
+ private isNewDocumentsTable;
404
+ private isNewChunksTable;
405
+ constructor(config: ResolvedConfig);
406
+ init(): Promise<void>;
407
+ /**
408
+ * 按需补齐索引:先经 listIndices 判存在,缺失的列才 createIndex(且 replace:false)。
409
+ * createIndex 默认 replace:true 会在每次启动时全量重建索引并提交新表版本——
410
+ * 这正是历史上「启动越来越慢 + _versions 目录膨胀」的根源,绝不可回退到无条件 createIndex。
411
+ */
412
+ private ensureIndexes;
413
+ /**
414
+ * 存储压实:逐表执行碎片合并 + 清理 retentionMs 之前的历史版本。
415
+ * 嵌入式场景下 LanceDB 不会自动做这件事,长期运行后版本/碎片无限累积会显著拖慢启动与查询。
416
+ */
417
+ optimizeStorage(retentionMs?: number): Promise<StorageOptimizeResult[]>;
418
+ /**
419
+ * 为存量 messages 表添加 parts 列(如果缺失)。
420
+ * LanceDB 0.14+ 支持 addColumns;旧版本会 throw,此时 rowToMessage 的 ?? "[]" 兜底。
421
+ */
422
+ private _ensurePartsColumn;
423
+ /**
424
+ * 为存量 topics 表添加 title 列(如果缺失)。
425
+ * 旧版本不支持 addColumns 时忽略,读取时 rowToTopic 的 ?? "" 兜底。
426
+ */
427
+ private _ensureTopicTitleColumn;
428
+ addMessages(messages: StoredMessage[]): Promise<void>;
429
+ addTopic(topic: Topic): Promise<void>;
430
+ updateTopicRecallCount(summaryId: string, count: number): Promise<void>;
431
+ getRecentTopics(chatId: string, userId: string, n1: number, n2: number, n3: number): Promise<{
432
+ detail: Topic[];
433
+ summary: Topic[];
434
+ concise: Topic[];
435
+ }>;
436
+ getMessagesSince(sessionId: string, since: number, limit?: number): Promise<StoredMessage[]>;
437
+ getLatestMessages(sessionId: string, limit: number): Promise<StoredMessage[]>;
438
+ /** 取某会话的全部消息(按 createdAt 升序),供管理面板分页切片使用 */
439
+ getAllMessagesBySession(sessionId: string): Promise<StoredMessage[]>;
440
+ searchMessages(vector: number[], filter?: string, limit?: number): Promise<Array<StoredMessage & {
441
+ _distance: number;
442
+ }>>;
443
+ hybridSearchMessages(query: string, vector: number[], filter?: string, limit?: number): Promise<StoredMessage[]>;
444
+ hybridSearchTopics(query: string, vector: number[], filter?: string, limit?: number): Promise<Topic[]>;
445
+ saveFact(fact: Fact): Promise<void>;
446
+ getAllFacts(): Promise<Fact[]>;
447
+ getAllSessionIds(): Promise<string[]>;
448
+ insertSession(session: Session): Promise<void>;
449
+ upsertSession(session: Session): Promise<void>;
450
+ getAllSessions(): Promise<Session[]>;
451
+ deleteSession(sessionId: string): Promise<void>;
452
+ /** 全量读取 topics(管理面板列表用,不做 recall 加权排序,按 endTime 倒序)*/
453
+ getAllTopics(): Promise<Topic[]>;
454
+ /** 删除单条 fact */
455
+ deleteFact(factId: string): Promise<void>;
456
+ /** 删除某会话下的全部消息(级联删除会话时使用)*/
457
+ deleteMessagesBySession(sessionId: string): Promise<void>;
458
+ /** 删除某会话下的全部 topics(级联删除会话时使用)*/
459
+ deleteTopicsBySession(sessionId: string): Promise<void>;
460
+ /** 各表行数统计(概览卡片用)*/
461
+ countAll(): Promise<{
462
+ sessions: number;
463
+ messages: number;
464
+ topics: number;
465
+ facts: number;
466
+ }>;
467
+ /**
468
+ * 按天聚合最近 days 天的活跃趋势(概览图表用)。
469
+ * 返回连续日期序列(含无数据的零值天),按本地日期分桶。
470
+ */
471
+ trendDaily(days: number): Promise<{
472
+ date: string;
473
+ sessions: number;
474
+ messages: number;
475
+ facts: number;
476
+ }[]>;
477
+ addDocument(doc: Document): Promise<void>;
478
+ addChunks(chunks: Chunk[]): Promise<void>;
479
+ updateDocumentGraphFlag(docId: string, hasGraph: boolean): Promise<void>;
480
+ getDocument(docId: string): Promise<Document | null>;
481
+ /** 查找同域同 hash 的文档(去重用)*/
482
+ findDocumentByHash(contentHash: string, filter?: string): Promise<Document | null>;
483
+ /** 按域过滤返回 docId 列表(chunkRedundantIds=false 时用于 chunk 过滤)*/
484
+ getDocIdsByDomain(filter?: string): Promise<string[]>;
485
+ /** 文档级粗召回:对摘要向量做向量搜索,定位候选文档 */
486
+ searchDocuments(vector: number[], filter?: string, limit?: number): Promise<Array<Document & {
487
+ _distance: number;
488
+ }>>;
489
+ /** 知识片段混合检索(BM25 + 向量),失败回退纯向量 */
490
+ searchChunks(query: string, vector: number[], filter?: string, limit?: number): Promise<Chunk[]>;
491
+ deleteDocument(docId: string): Promise<void>;
492
+ deleteChunksByDoc(docId: string): Promise<void>;
493
+ /** 全量读取文档(管理面板用),按更新时间倒序 */
494
+ getAllDocuments(): Promise<Document[]>;
495
+ /** 知识库行数统计 */
496
+ countKnowledge(): Promise<{
497
+ documents: number;
498
+ chunks: number;
499
+ }>;
500
+ /**
501
+ * 根据 metadata 字段内容构建 SQL LIKE 过滤条件。
502
+ *
503
+ * metadata 以 JSON 字符串存储,此方法将键值对转换为 SQL LIKE 表达式,
504
+ * 可直接传给 searchMessages / hybridSearchTopics 的 filter 参数。
505
+ *
506
+ * 示例:buildMetadataFilter({ env: "prod", version: 2 })
507
+ * → `metadata LIKE '%"env":"prod"%' AND metadata LIKE '%"version":2%'`
508
+ *
509
+ * 注意:仅适合简单标量值(字符串、数字、布尔)的精确匹配。
510
+ * 复杂嵌套对象或含空格的 JSON 值可能无法可靠匹配。
511
+ */
512
+ static buildMetadataFilter(conditions: Record<string, string | number | boolean>): string;
513
+ }
514
+
365
515
  declare class MemoryManager {
366
516
  private readonly config;
367
517
  private readonly lance;
@@ -375,10 +525,16 @@ declare class MemoryManager {
375
525
  private readonly sessionMap;
376
526
  constructor(config: MemoryConfig);
377
527
  init(): Promise<void>;
528
+ /**
529
+ * 手动触发存储压实与历史版本清理(init 后台会自动执行一次;上层维护任务也可调用)。
530
+ * @param retentionMs 保留多久内的历史版本,默认取配置 optimizeVersionRetentionMs
531
+ */
532
+ optimizeStorage(retentionMs?: number): Promise<StorageOptimizeResult[]>;
378
533
  private restoreFromStorage;
379
534
  updateChat(messages: RawMessage[], opts?: UpdateChatOptions): Promise<void>;
380
535
  flushChat(sessionId?: string, opts?: {
381
536
  wait?: boolean;
537
+ waitGraph?: boolean;
382
538
  }): Promise<void>;
383
539
  updateFacts(content: string, level: FactLevel, userId: string, chatId: string, sessionId?: string): Promise<void>;
384
540
  updateEntity(entities: Entity[], relations: Relation[], context?: UpdateEntityOptions): Promise<void>;
@@ -536,120 +692,6 @@ declare class MemoryManager {
536
692
  destroy(): void;
537
693
  }
538
694
 
539
- declare class LanceService {
540
- private readonly config;
541
- private conn;
542
- private messagesTable;
543
- private topicsTable;
544
- private factsTable;
545
- private sessionsTable;
546
- private documentsTable;
547
- private chunksTable;
548
- private isNewMessagesTable;
549
- private isNewSessionsTable;
550
- private isNewDocumentsTable;
551
- private isNewChunksTable;
552
- constructor(config: ResolvedConfig);
553
- init(): Promise<void>;
554
- private ensureFtsIndexes;
555
- /**
556
- * 为存量 messages 表添加 parts 列(如果缺失)。
557
- * LanceDB 0.14+ 支持 addColumns;旧版本会 throw,此时 rowToMessage 的 ?? "[]" 兜底。
558
- */
559
- private _ensurePartsColumn;
560
- /**
561
- * 为存量 topics 表添加 title 列(如果缺失)。
562
- * 旧版本不支持 addColumns 时忽略,读取时 rowToTopic 的 ?? "" 兜底。
563
- */
564
- private _ensureTopicTitleColumn;
565
- private ensureScalarIndex;
566
- addMessages(messages: StoredMessage[]): Promise<void>;
567
- addTopic(topic: Topic): Promise<void>;
568
- updateTopicRecallCount(summaryId: string, count: number): Promise<void>;
569
- getRecentTopics(chatId: string, userId: string, n1: number, n2: number, n3: number): Promise<{
570
- detail: Topic[];
571
- summary: Topic[];
572
- concise: Topic[];
573
- }>;
574
- getMessagesSince(sessionId: string, since: number, limit?: number): Promise<StoredMessage[]>;
575
- getLatestMessages(sessionId: string, limit: number): Promise<StoredMessage[]>;
576
- /** 取某会话的全部消息(按 createdAt 升序),供管理面板分页切片使用 */
577
- getAllMessagesBySession(sessionId: string): Promise<StoredMessage[]>;
578
- searchMessages(vector: number[], filter?: string, limit?: number): Promise<Array<StoredMessage & {
579
- _distance: number;
580
- }>>;
581
- hybridSearchMessages(query: string, vector: number[], filter?: string, limit?: number): Promise<StoredMessage[]>;
582
- hybridSearchTopics(query: string, vector: number[], filter?: string, limit?: number): Promise<Topic[]>;
583
- saveFact(fact: Fact): Promise<void>;
584
- getAllFacts(): Promise<Fact[]>;
585
- getAllSessionIds(): Promise<string[]>;
586
- insertSession(session: Session): Promise<void>;
587
- upsertSession(session: Session): Promise<void>;
588
- getAllSessions(): Promise<Session[]>;
589
- deleteSession(sessionId: string): Promise<void>;
590
- /** 全量读取 topics(管理面板列表用,不做 recall 加权排序,按 endTime 倒序)*/
591
- getAllTopics(): Promise<Topic[]>;
592
- /** 删除单条 fact */
593
- deleteFact(factId: string): Promise<void>;
594
- /** 删除某会话下的全部消息(级联删除会话时使用)*/
595
- deleteMessagesBySession(sessionId: string): Promise<void>;
596
- /** 删除某会话下的全部 topics(级联删除会话时使用)*/
597
- deleteTopicsBySession(sessionId: string): Promise<void>;
598
- /** 各表行数统计(概览卡片用)*/
599
- countAll(): Promise<{
600
- sessions: number;
601
- messages: number;
602
- topics: number;
603
- facts: number;
604
- }>;
605
- /**
606
- * 按天聚合最近 days 天的活跃趋势(概览图表用)。
607
- * 返回连续日期序列(含无数据的零值天),按本地日期分桶。
608
- */
609
- trendDaily(days: number): Promise<{
610
- date: string;
611
- sessions: number;
612
- messages: number;
613
- facts: number;
614
- }[]>;
615
- addDocument(doc: Document): Promise<void>;
616
- addChunks(chunks: Chunk[]): Promise<void>;
617
- updateDocumentGraphFlag(docId: string, hasGraph: boolean): Promise<void>;
618
- getDocument(docId: string): Promise<Document | null>;
619
- /** 查找同域同 hash 的文档(去重用)*/
620
- findDocumentByHash(contentHash: string, filter?: string): Promise<Document | null>;
621
- /** 按域过滤返回 docId 列表(chunkRedundantIds=false 时用于 chunk 过滤)*/
622
- getDocIdsByDomain(filter?: string): Promise<string[]>;
623
- /** 文档级粗召回:对摘要向量做向量搜索,定位候选文档 */
624
- searchDocuments(vector: number[], filter?: string, limit?: number): Promise<Array<Document & {
625
- _distance: number;
626
- }>>;
627
- /** 知识片段混合检索(BM25 + 向量),失败回退纯向量 */
628
- searchChunks(query: string, vector: number[], filter?: string, limit?: number): Promise<Chunk[]>;
629
- deleteDocument(docId: string): Promise<void>;
630
- deleteChunksByDoc(docId: string): Promise<void>;
631
- /** 全量读取文档(管理面板用),按更新时间倒序 */
632
- getAllDocuments(): Promise<Document[]>;
633
- /** 知识库行数统计 */
634
- countKnowledge(): Promise<{
635
- documents: number;
636
- chunks: number;
637
- }>;
638
- /**
639
- * 根据 metadata 字段内容构建 SQL LIKE 过滤条件。
640
- *
641
- * metadata 以 JSON 字符串存储,此方法将键值对转换为 SQL LIKE 表达式,
642
- * 可直接传给 searchMessages / hybridSearchTopics 的 filter 参数。
643
- *
644
- * 示例:buildMetadataFilter({ env: "prod", version: 2 })
645
- * → `metadata LIKE '%"env":"prod"%' AND metadata LIKE '%"version":2%'`
646
- *
647
- * 注意:仅适合简单标量值(字符串、数字、布尔)的精确匹配。
648
- * 复杂嵌套对象或含空格的 JSON 值可能无法可靠匹配。
649
- */
650
- static buildMetadataFilter(conditions: Record<string, string | number | boolean>): string;
651
- }
652
-
653
695
  declare const DEFAULT_NODE_TYPES: readonly ["Person", "Group", "Organization", "Project", "Task", "Decision", "Plan", "Event", "Product", "Technology", "Data", "Document", "Topic", "Concept", "Preference", "Habit", "Goal", "Skill", "Attribute", "Value", "Status", "Time", "Location", "Resource", "Relationship"];
654
696
  declare const DEFAULT_RELATION_TYPES: readonly ["is_a", "part_of", "belongs_to", "contains", "has_member", "mentioned_in", "refers_to", "same_as", "alias_of", "related_to", "associated_with", "uses", "creates", "updates", "buys", "owns", "consumes", "works_on", "prefers", "likes", "dislikes", "interested_in", "favorite", "plans", "decides", "habit_of", "tends_to", "avoids", "skilled_in", "learning", "knows", "friends_with", "married_to", "parent_of", "child_of", "lives_with", "depends_on", "built_with", "integrates_with", "deployed_on", "inputs", "outputs", "trained_on", "predicts", "happens_at", "started_at", "ended_at", "affects", "causes", "leads_to", "improves", "reduces", "assigned_to", "executed_by", "blocks", "completes", "describes", "explains", "references"];
655
697
  type NodeType = (typeof DEFAULT_NODE_TYPES)[number];
@@ -658,4 +700,4 @@ type RelationType = (typeof DEFAULT_RELATION_TYPES)[number];
658
700
  declare const KIND_CONVERSATION = "conversation";
659
701
  declare const KIND_KNOWLEDGE = "knowledge";
660
702
 
661
- export { type AddDocumentOptions, type BuildGraphMode, type Chunk, type ChunkHit, type ChunkPiece, type CompressOutput, type ContentPart, DEFAULT_NODE_TYPES, DEFAULT_RELATION_TYPES, type Document, type DomainIds, type Entity, type EntityMeta, type Fact, type FactLevel, KIND_CONVERSATION, KIND_KNOWLEDGE, type KnowledgeSearchOptions, type KnowledgeSearchResult, LanceService, type MemoryConfig, MemoryManager, type MessageType, type NodeType, type PageParams, type Paginated, type RawMessage, type Relation, type RelationType, type SearchMode, type SearchOptions, type SearchResult, type SearchScope, type Session, type SessionEntry, type SessionSearchOptions, type SessionView, type StoredMessage, type Topic, type UpdateChatOptions, type UpdateEntityOptions, type UpdateSessionOptions };
703
+ export { type AddDocumentOptions, type BuildGraphMode, type Chunk, type ChunkHit, type ChunkPiece, type CompressOutput, type ContentPart, DEFAULT_NODE_TYPES, DEFAULT_RELATION_TYPES, type Document, type DomainIds, type Entity, type EntityMeta, type Fact, type FactLevel, KIND_CONVERSATION, KIND_KNOWLEDGE, type KnowledgeSearchOptions, type KnowledgeSearchResult, LanceService, type MemoryConfig, MemoryManager, type MessageType, type NodeType, type PageParams, type Paginated, type RawMessage, type Relation, type RelationType, type SearchMode, type SearchOptions, type SearchResult, type SearchScope, type Session, type SessionEntry, type SessionSearchOptions, type SessionView, type StorageOptimizeResult, type StoredMessage, type Topic, type UpdateChatOptions, type UpdateEntityOptions, type UpdateSessionOptions };