@yun-zero/claw-memory 0.1.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 (131) hide show
  1. package/.claude/settings.local.json +68 -0
  2. package/README.md +323 -0
  3. package/dist/config/llm.d.ts +13 -0
  4. package/dist/config/llm.d.ts.map +1 -0
  5. package/dist/config/llm.js +96 -0
  6. package/dist/config/llm.js.map +1 -0
  7. package/dist/config/plugin.d.ts +15 -0
  8. package/dist/config/plugin.d.ts.map +1 -0
  9. package/dist/config/plugin.js +32 -0
  10. package/dist/config/plugin.js.map +1 -0
  11. package/dist/db/entityRepository.d.ts +21 -0
  12. package/dist/db/entityRepository.d.ts.map +1 -0
  13. package/dist/db/entityRepository.js +55 -0
  14. package/dist/db/entityRepository.js.map +1 -0
  15. package/dist/db/repository.d.ts +22 -0
  16. package/dist/db/repository.d.ts.map +1 -0
  17. package/dist/db/repository.js +77 -0
  18. package/dist/db/repository.js.map +1 -0
  19. package/dist/db/schema.d.ts +5 -0
  20. package/dist/db/schema.d.ts.map +1 -0
  21. package/dist/db/schema.js +112 -0
  22. package/dist/db/schema.js.map +1 -0
  23. package/dist/db/todoRepository.d.ts +26 -0
  24. package/dist/db/todoRepository.d.ts.map +1 -0
  25. package/dist/db/todoRepository.js +54 -0
  26. package/dist/db/todoRepository.js.map +1 -0
  27. package/dist/hooks/bootstrap.d.ts +3 -0
  28. package/dist/hooks/bootstrap.d.ts.map +1 -0
  29. package/dist/hooks/bootstrap.js +28 -0
  30. package/dist/hooks/bootstrap.js.map +1 -0
  31. package/dist/hooks/message.d.ts +18 -0
  32. package/dist/hooks/message.d.ts.map +1 -0
  33. package/dist/hooks/message.js +52 -0
  34. package/dist/hooks/message.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +46 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/mcp/tools.d.ts +26 -0
  40. package/dist/mcp/tools.d.ts.map +1 -0
  41. package/dist/mcp/tools.js +360 -0
  42. package/dist/mcp/tools.js.map +1 -0
  43. package/dist/plugin.d.ts +18 -0
  44. package/dist/plugin.d.ts.map +1 -0
  45. package/dist/plugin.js +62 -0
  46. package/dist/plugin.js.map +1 -0
  47. package/dist/services/entityGraphService.d.ts +87 -0
  48. package/dist/services/entityGraphService.d.ts.map +1 -0
  49. package/dist/services/entityGraphService.js +271 -0
  50. package/dist/services/entityGraphService.js.map +1 -0
  51. package/dist/services/memory.d.ts +26 -0
  52. package/dist/services/memory.d.ts.map +1 -0
  53. package/dist/services/memory.js +281 -0
  54. package/dist/services/memory.js.map +1 -0
  55. package/dist/services/memoryIndex.d.ts +34 -0
  56. package/dist/services/memoryIndex.d.ts.map +1 -0
  57. package/dist/services/memoryIndex.js +100 -0
  58. package/dist/services/memoryIndex.js.map +1 -0
  59. package/dist/services/metadataExtractor.d.ts +16 -0
  60. package/dist/services/metadataExtractor.d.ts.map +1 -0
  61. package/dist/services/metadataExtractor.js +75 -0
  62. package/dist/services/metadataExtractor.js.map +1 -0
  63. package/dist/services/retrieval.d.ts +24 -0
  64. package/dist/services/retrieval.d.ts.map +1 -0
  65. package/dist/services/retrieval.js +40 -0
  66. package/dist/services/retrieval.js.map +1 -0
  67. package/dist/services/scheduler.d.ts +122 -0
  68. package/dist/services/scheduler.d.ts.map +1 -0
  69. package/dist/services/scheduler.js +434 -0
  70. package/dist/services/scheduler.js.map +1 -0
  71. package/dist/services/summarizer.d.ts +43 -0
  72. package/dist/services/summarizer.d.ts.map +1 -0
  73. package/dist/services/summarizer.js +252 -0
  74. package/dist/services/summarizer.js.map +1 -0
  75. package/dist/services/tagService.d.ts +64 -0
  76. package/dist/services/tagService.d.ts.map +1 -0
  77. package/dist/services/tagService.js +281 -0
  78. package/dist/services/tagService.js.map +1 -0
  79. package/dist/tools/memory.d.ts +3 -0
  80. package/dist/tools/memory.d.ts.map +1 -0
  81. package/dist/tools/memory.js +114 -0
  82. package/dist/tools/memory.js.map +1 -0
  83. package/dist/types.d.ts +128 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +6 -0
  86. package/dist/types.js.map +1 -0
  87. package/docs/plans/2026-03-02-claw-memory-design.md +445 -0
  88. package/docs/plans/2026-03-02-incremental-summary-design.md +157 -0
  89. package/docs/plans/2026-03-02-incremental-summary-implementation.md +468 -0
  90. package/docs/plans/2026-03-02-memory-index-design.md +163 -0
  91. package/docs/plans/2026-03-02-memory-index-implementation.md +836 -0
  92. package/docs/plans/2026-03-02-mvp-implementation.md +1703 -0
  93. package/docs/plans/2026-03-02-testing-implementation.md +395 -0
  94. package/docs/plans/2026-03-02-testing-plan.md +93 -0
  95. package/docs/plans/2026-03-03-claw-memory-openclaw-plugin-design.md +285 -0
  96. package/docs/plans/2026-03-03-claw-memory-plugin-implementation.md +642 -0
  97. package/docs/plans/2026-03-03-entity-graph-design.md +121 -0
  98. package/docs/plans/2026-03-03-entity-graph-implementation.md +687 -0
  99. package/docs/plans/2026-03-03-llm-generic-config-design.md +43 -0
  100. package/docs/plans/2026-03-03-llm-generic-config-implementation.md +186 -0
  101. package/docs/plans/2026-03-03-memory-e2e-stress-test-design.md +110 -0
  102. package/docs/plans/2026-03-03-memory-e2e-stress-test-implementation.md +464 -0
  103. package/docs/plans/2026-03-03-minimax-llm-fix.md +156 -0
  104. package/docs/plans/2026-03-03-scheduler-design.md +165 -0
  105. package/docs/plans/2026-03-03-scheduler-implementation.md +777 -0
  106. package/docs/plans/2026-03-03-tags-visualization-design.md +73 -0
  107. package/docs/plans/2026-03-03-tags-visualization-implementation.md +539 -0
  108. package/openclaw.plugin.json +11 -0
  109. package/package.json +41 -0
  110. package/src/config/llm.ts +129 -0
  111. package/src/config/plugin.ts +47 -0
  112. package/src/db/entityRepository.ts +80 -0
  113. package/src/db/repository.ts +106 -0
  114. package/src/db/schema.ts +121 -0
  115. package/src/db/todoRepository.ts +76 -0
  116. package/src/hooks/bootstrap.ts +36 -0
  117. package/src/hooks/message.ts +84 -0
  118. package/src/index.ts +50 -0
  119. package/src/plugin.ts +85 -0
  120. package/src/services/entityGraphService.ts +367 -0
  121. package/src/services/memory.ts +338 -0
  122. package/src/services/memoryIndex.ts +140 -0
  123. package/src/services/metadataExtractor.ts +89 -0
  124. package/src/services/retrieval.ts +71 -0
  125. package/src/services/scheduler.ts +529 -0
  126. package/src/services/summarizer.ts +318 -0
  127. package/src/services/tagService.ts +335 -0
  128. package/src/tools/memory.ts +137 -0
  129. package/src/types.ts +139 -0
  130. package/tsconfig.json +20 -0
  131. package/vitest.config.ts +16 -0
@@ -0,0 +1,100 @@
1
+ import { TodoRepository } from '../db/todoRepository.js';
2
+ import { MemoryRepository } from '../db/repository.js';
3
+ export async function getMemoryIndex(db, options) {
4
+ const { startDate, endDate } = calculatePeriodRange(options.period, options.date);
5
+ // 并行获取活跃领域
6
+ const [tags, keywords] = await Promise.all([
7
+ Promise.resolve(getTopTags(db, startDate, endDate, 10)),
8
+ Promise.resolve(getTopKeywords(db, startDate, endDate, 10))
9
+ ]);
10
+ // 并行获取待办和最近动态
11
+ const [todos, recentActivity] = await Promise.all([
12
+ options.includeTodos
13
+ ? getTodos(db, options.period, endDate)
14
+ : Promise.resolve([]),
15
+ options.includeRecent
16
+ ? getRecentActivity(db, startDate, endDate, options.recentLimit || 5)
17
+ : Promise.resolve([])
18
+ ]);
19
+ // 获取缓存的整体摘要(从最新的 memory)
20
+ const memoryRepo = new MemoryRepository(db);
21
+ const rawSummary = memoryRepo.getLatestIntegratedSummary();
22
+ // Convert null to undefined to match the interface type
23
+ const integratedSummary = rawSummary === null ? undefined : rawSummary;
24
+ return {
25
+ period: { start: startDate, end: endDate },
26
+ activeAreas: { tags, keywords },
27
+ todos,
28
+ recentActivity,
29
+ integratedSummary
30
+ };
31
+ }
32
+ async function getTodos(db, period, endDate) {
33
+ const todoRepo = new TodoRepository(db);
34
+ const allTodos = todoRepo.findByPeriod(period, endDate);
35
+ return allTodos
36
+ .filter(t => !t.completedAt)
37
+ .map(t => ({ id: t.id, content: t.content, period: t.period }));
38
+ }
39
+ async function getRecentActivity(db, startDate, endDate, limit) {
40
+ const recentMemories = findMemoriesByDateRange(db, startDate, endDate, limit);
41
+ return recentMemories.map(m => ({
42
+ date: m.createdAt.toISOString().split('T')[0],
43
+ summary: m.summary || ''
44
+ }));
45
+ }
46
+ function calculatePeriodRange(period, date) {
47
+ const endDate = date || new Date().toISOString().split('T')[0];
48
+ const startDate = new Date(endDate);
49
+ switch (period) {
50
+ case 'day': break;
51
+ case 'week':
52
+ startDate.setDate(startDate.getDate() - 7);
53
+ break;
54
+ case 'month':
55
+ startDate.setMonth(startDate.getMonth() - 1);
56
+ break;
57
+ }
58
+ return {
59
+ startDate: startDate.toISOString().split('T')[0],
60
+ endDate
61
+ };
62
+ }
63
+ function getTopTags(db, startDate, endDate, limit) {
64
+ const rows = db.prepare(`
65
+ SELECT e.name, COUNT(me.memory_id) as count
66
+ FROM memory_entities me
67
+ JOIN entities e ON me.entity_id = e.id
68
+ JOIN memories m ON me.memory_id = m.id
69
+ WHERE e.type = 'tag' AND date(m.created_at) BETWEEN ? AND ?
70
+ GROUP BY e.id ORDER BY count DESC LIMIT ?
71
+ `).all(startDate, endDate, limit);
72
+ return rows;
73
+ }
74
+ function getTopKeywords(db, startDate, endDate, limit) {
75
+ const rows = db.prepare(`
76
+ SELECT e.name FROM memory_entities me
77
+ JOIN entities e ON me.entity_id = e.id
78
+ JOIN memories m ON me.memory_id = m.id
79
+ WHERE e.type = 'keyword' AND date(m.created_at) BETWEEN ? AND ?
80
+ GROUP BY e.id ORDER BY COUNT(*) DESC LIMIT ?
81
+ `).all(startDate, endDate, limit);
82
+ return rows.map(r => r.name);
83
+ }
84
+ function findMemoriesByDateRange(db, startDate, endDate, limit) {
85
+ const rows = db.prepare(`
86
+ SELECT id, content_path, summary, created_at, importance
87
+ FROM memories
88
+ WHERE date(created_at) BETWEEN ? AND ?
89
+ ORDER BY created_at DESC
90
+ LIMIT ?
91
+ `).all(startDate, endDate, limit);
92
+ return rows.map(row => ({
93
+ id: row.id,
94
+ contentPath: row.content_path,
95
+ summary: row.summary,
96
+ createdAt: new Date(row.created_at),
97
+ importance: row.importance
98
+ }));
99
+ }
100
+ //# sourceMappingURL=memoryIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryIndex.js","sourceRoot":"","sources":["../../src/services/memoryIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { IntegratedSummary } from '../types.js';
2
+ export interface ExtractedMetadata {
3
+ tags: string[];
4
+ keywords: string[];
5
+ subjects: string[];
6
+ importance: number;
7
+ summary: string;
8
+ integratedSummary: IntegratedSummary;
9
+ }
10
+ export declare class MetadataExtractor {
11
+ extract(content: string, existingSummary?: IntegratedSummary): Promise<ExtractedMetadata>;
12
+ callLLM(prompt: string): Promise<ExtractedMetadata>;
13
+ private parseLLMResponse;
14
+ private fallbackExtract;
15
+ }
16
+ //# sourceMappingURL=metadataExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataExtractor.d.ts","sourceRoot":"","sources":["../../src/services/metadataExtractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AA6BD,qBAAa,iBAAiB;IACtB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmBzF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAKzD,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,eAAe;CAcxB"}
@@ -0,0 +1,75 @@
1
+ import { generateSummaryWithLLM } from '../config/llm.js';
2
+ const EXTRACTION_PROMPT = `请从以下对话内容中提取结构化元数据,并整合已有的整体摘要:
3
+
4
+ 当前对话内容:
5
+ {content}
6
+
7
+ 已有整体摘要(请在此基础上增量更新):
8
+ {existing_summary}
9
+
10
+ 请以 JSON 格式返回:
11
+ {
12
+ "tags": ["一级分类/二级分类"],
13
+ "keywords": ["关键词1", "关键词2"],
14
+ "subjects": ["主题1"],
15
+ "importance": 0.0-1.0,
16
+ "summary": "当前对话的一句话摘要",
17
+ "integrated_summary": {
18
+ "active_areas": ["领域名 (出现次数)"],
19
+ "key_topics": ["主题1", "主题2"],
20
+ "recent_summary": "整体摘要自然语言描述"
21
+ }
22
+ }
23
+
24
+ 注意:
25
+ - tags 使用层级结构
26
+ - integrated_summary 需整合历史信息,在已有基础上增加新领域
27
+ - 只返回 JSON,不要其他内容`;
28
+ export class MetadataExtractor {
29
+ async extract(content, existingSummary) {
30
+ let existingSummaryText = '无';
31
+ if (existingSummary) {
32
+ existingSummaryText = `活跃领域: ${existingSummary.active_areas.join(', ')}\n关键词: ${existingSummary.key_topics.join(', ')}\n近期摘要: ${existingSummary.recent_summary}`;
33
+ }
34
+ const prompt = EXTRACTION_PROMPT
35
+ .replace('{content}', content)
36
+ .replace('{existing_summary}', existingSummaryText);
37
+ try {
38
+ const response = await generateSummaryWithLLM(prompt);
39
+ return this.parseLLMResponse(response);
40
+ }
41
+ catch (error) {
42
+ console.warn('LLM extraction failed:', error);
43
+ return this.fallbackExtract(content);
44
+ }
45
+ }
46
+ async callLLM(prompt) {
47
+ const response = await generateSummaryWithLLM(prompt);
48
+ return this.parseLLMResponse(response);
49
+ }
50
+ parseLLMResponse(response) {
51
+ try {
52
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
53
+ if (jsonMatch) {
54
+ return JSON.parse(jsonMatch[0]);
55
+ }
56
+ }
57
+ catch { }
58
+ return this.fallbackExtract('');
59
+ }
60
+ fallbackExtract(content) {
61
+ return {
62
+ tags: [],
63
+ keywords: [],
64
+ subjects: [],
65
+ importance: 0.5,
66
+ summary: content.substring(0, 100),
67
+ integratedSummary: {
68
+ active_areas: [],
69
+ key_topics: [],
70
+ recent_summary: ''
71
+ }
72
+ };
73
+ }
74
+ }
75
+ //# sourceMappingURL=metadataExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataExtractor.js","sourceRoot":"","sources":["../../src/services/metadataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAY1D,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;kBAyBR,CAAC;AAEnB,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,eAAmC;QAChE,IAAI,mBAAmB,GAAG,GAAG,CAAC;QAC9B,IAAI,eAAe,EAAE,CAAC;YACpB,mBAAmB,GAAG,SAAS,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,eAAe,CAAC,cAAc,EAAE,CAAC;QACnK,CAAC;QAED,MAAM,MAAM,GAAG,iBAAiB;aAC7B,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;aAC7B,OAAO,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;QAEtD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,gBAAgB,CAAC,QAAgB;QACvC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAChD,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,OAAO,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAEO,eAAe,CAAC,OAAe;QACrC,OAAO;YACL,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;YAClC,iBAAiB,EAAE;gBACjB,YAAY,EAAE,EAAE;gBAChB,UAAU,EAAE,EAAE;gBACd,cAAc,EAAE,EAAE;aACnB;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ export interface TimeDecayConfig {
2
+ today: number;
3
+ week: number;
4
+ month: number;
5
+ year: number;
6
+ older: number;
7
+ }
8
+ export interface WeightInput {
9
+ entityMatch: number;
10
+ timeDecay: TimeDecayConfig;
11
+ memoryDate: string;
12
+ tagMatch: number;
13
+ importance: number;
14
+ }
15
+ export declare const DEFAULT_TIME_DECAY: TimeDecayConfig;
16
+ export declare function calculateWeight(input: WeightInput): number;
17
+ export interface SearchOptions {
18
+ query: string;
19
+ timeRange?: 'today' | 'week' | 'month' | 'year' | 'all';
20
+ tags?: string[];
21
+ limit?: number;
22
+ maxTokens?: number;
23
+ }
24
+ //# sourceMappingURL=retrieval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/services/retrieval.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,eAAe,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAMhC,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAwB1D;AAcD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACxD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,40 @@
1
+ export const DEFAULT_TIME_DECAY = {
2
+ today: 30,
3
+ week: 20,
4
+ month: 10,
5
+ year: 5,
6
+ older: 0
7
+ };
8
+ export function calculateWeight(input) {
9
+ const { entityMatch, timeDecay, memoryDate, tagMatch, importance } = input;
10
+ // 实体匹配权重 (0-40)
11
+ const entityWeight = Math.min(entityMatch * 10, 40);
12
+ // 时间衰减权重 (0-30)
13
+ const timeWeight = getTimeWeight(memoryDate, timeDecay);
14
+ // 标签层级权重 (0-20)
15
+ const tagWeight = Math.min(tagMatch * 2, 20);
16
+ // 重要性权重 (0-10)
17
+ const importanceWeight = importance * 10;
18
+ // 总分 = 实体匹配 × 0.4 + 时间衰减 × 0.3 + 标签层级 × 0.2 + 重要性 × 0.1
19
+ // 归一化到 0-100
20
+ const total = entityWeight * 0.4 +
21
+ timeWeight * 0.3 +
22
+ tagWeight * 0.2 +
23
+ importanceWeight * 0.1;
24
+ return Math.round(total * 10) / 10;
25
+ }
26
+ function getTimeWeight(memoryDate, config) {
27
+ const today = new Date();
28
+ const memory = new Date(memoryDate);
29
+ const diffDays = Math.floor((today.getTime() - memory.getTime()) / (1000 * 60 * 60 * 24));
30
+ if (diffDays === 0)
31
+ return config.today;
32
+ if (diffDays <= 7)
33
+ return config.week;
34
+ if (diffDays <= 30)
35
+ return config.month;
36
+ if (diffDays <= 365)
37
+ return config.year;
38
+ return config.older;
39
+ }
40
+ //# sourceMappingURL=retrieval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.js","sourceRoot":"","sources":["../../src/services/retrieval.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,kBAAkB,GAAoB;IACjD,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAE3E,gBAAgB;IAChB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IAEpD,gBAAgB;IAChB,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAExD,gBAAgB;IAChB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAE7C,eAAe;IACf,MAAM,gBAAgB,GAAG,UAAU,GAAG,EAAE,CAAC;IAEzC,wDAAwD;IACxD,aAAa;IACb,MAAM,KAAK,GACT,YAAY,GAAG,GAAG;QAClB,UAAU,GAAG,GAAG;QAChB,SAAS,GAAG,GAAG;QACf,gBAAgB,GAAG,GAAG,CAAC;IAEzB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,aAAa,CAAC,UAAkB,EAAE,MAAuB;IAChE,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAE1F,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACxC,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACtC,IAAI,QAAQ,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACxC,IAAI,QAAQ,IAAI,GAAG;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACxC,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Scheduler Service
3
+ * Manages scheduled tasks for deduplication and summary generation
4
+ */
5
+ import Database from 'better-sqlite3';
6
+ /**
7
+ * Scheduler configuration interface
8
+ */
9
+ export interface SchedulerConfig {
10
+ /** Time to run deduplication task (HH:mm format, e.g., "01:00") */
11
+ deduplicateTime: string;
12
+ /** Time to run daily summary task (HH:mm format) */
13
+ dailyTime: string;
14
+ /** Time to run weekly summary task (HH:mm format) */
15
+ weeklyTime: string;
16
+ /** Time to run monthly summary task (HH:mm format) */
17
+ monthlyTime: string;
18
+ /** Whether the scheduler is enabled */
19
+ enabled: boolean;
20
+ }
21
+ /**
22
+ * Default scheduler configuration
23
+ */
24
+ export declare const DEFAULT_CONFIG: SchedulerConfig;
25
+ /**
26
+ * Scheduler Service Class
27
+ * Manages scheduled tasks with execution locking and task queue
28
+ */
29
+ export declare class Scheduler {
30
+ private config;
31
+ private isRunning;
32
+ private taskQueue;
33
+ private tasks;
34
+ private db;
35
+ /**
36
+ * Creates a new Scheduler instance
37
+ * @param db - Database instance
38
+ * @param config - Optional configuration (uses DEFAULT_CONFIG if not provided)
39
+ */
40
+ constructor(db: Database.Database, config?: Partial<SchedulerConfig>);
41
+ /**
42
+ * Starts the scheduler and all scheduled tasks
43
+ */
44
+ start(): void;
45
+ /**
46
+ * Stops the scheduler and all scheduled tasks
47
+ */
48
+ stop(): void;
49
+ /**
50
+ * Checks if the scheduler is enabled
51
+ * @returns true if enabled, false otherwise
52
+ */
53
+ isEnabled(): boolean;
54
+ /**
55
+ * Checks if the scheduler is currently running
56
+ * @returns true if running, false otherwise
57
+ */
58
+ getIsRunning(): boolean;
59
+ /**
60
+ * Converts HH:mm time format to cron expression
61
+ * @param time - Time in HH:mm format
62
+ * @returns Cron expression
63
+ */
64
+ private timeToCron;
65
+ /**
66
+ * Schedules the deduplicate task
67
+ */
68
+ private scheduleDeduplicate;
69
+ /**
70
+ * Schedules the daily summary task
71
+ */
72
+ private scheduleDailySummary;
73
+ /**
74
+ * Schedules the weekly summary task
75
+ */
76
+ private scheduleWeeklySummary;
77
+ /**
78
+ * Schedules the monthly summary task
79
+ */
80
+ private scheduleMonthlySummary;
81
+ /**
82
+ * Executes a task with locking mechanism and queue support
83
+ * @param type - Task type
84
+ */
85
+ private executeWithLock;
86
+ /**
87
+ * Processes the task queue
88
+ */
89
+ private processQueue;
90
+ /**
91
+ * Executes deduplication task - finds and marks duplicate memories
92
+ */
93
+ private deduplicate;
94
+ /**
95
+ * Executes daily summary task - generates summary for previous day's memories
96
+ */
97
+ private dailySummary;
98
+ /**
99
+ * Executes weekly summary task
100
+ */
101
+ private weeklySummary;
102
+ /**
103
+ * Executes monthly summary task
104
+ */
105
+ private monthlySummary;
106
+ /**
107
+ * Updates the scheduler configuration
108
+ * @param config - New configuration (partial)
109
+ */
110
+ updateConfig(config: Partial<SchedulerConfig>): void;
111
+ /**
112
+ * Gets the current configuration
113
+ * @returns Current scheduler configuration
114
+ */
115
+ getConfig(): SchedulerConfig;
116
+ /**
117
+ * Gets the current queue size
118
+ * @returns Number of pending tasks in queue
119
+ */
120
+ getQueueSize(): number;
121
+ }
122
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/services/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,eAM5B,CAAC;AAeF;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,EAAE,CAAoB;IAE9B;;;;OAIG;gBACS,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IA2BpE;;OAEG;IACH,KAAK,IAAI,IAAI;IAsBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAoBZ;;;OAGG;IACH,SAAS,IAAI,OAAO;IAIpB;;;OAGG;IACH,YAAY,IAAI,OAAO;IAIvB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,YAAY;IA+B1B;;OAEG;YACW,WAAW;IAqDzB;;OAEG;YACW,YAAY;IA2D1B;;OAEG;YACW,aAAa;IAiE3B;;OAEG;YACW,cAAc;IA8C5B;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAKpD;;;OAGG;IACH,SAAS,IAAI,eAAe;IAI5B;;;OAGG;IACH,YAAY,IAAI,MAAM;CAGvB"}