@alexandrgreen/anchorclaw 0.0.3

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 (247) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +9 -0
  3. package/README.md +252 -0
  4. package/dist/api.d.ts +3 -0
  5. package/dist/api.d.ts.map +1 -0
  6. package/dist/api.js +3 -0
  7. package/dist/api.js.map +1 -0
  8. package/dist/config.d.ts +46 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +309 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/config.test.d.ts +2 -0
  13. package/dist/config.test.d.ts.map +1 -0
  14. package/dist/config.test.js +100 -0
  15. package/dist/config.test.js.map +1 -0
  16. package/dist/identity-policy.d.ts +3 -0
  17. package/dist/identity-policy.d.ts.map +1 -0
  18. package/dist/identity-policy.js +7 -0
  19. package/dist/identity-policy.js.map +1 -0
  20. package/dist/identity-policy.test.d.ts +2 -0
  21. package/dist/identity-policy.test.d.ts.map +1 -0
  22. package/dist/identity-policy.test.js +23 -0
  23. package/dist/identity-policy.test.js.map +1 -0
  24. package/dist/identity.d.ts +22 -0
  25. package/dist/identity.d.ts.map +1 -0
  26. package/dist/identity.js +113 -0
  27. package/dist/identity.js.map +1 -0
  28. package/dist/identity.test.d.ts +2 -0
  29. package/dist/identity.test.d.ts.map +1 -0
  30. package/dist/identity.test.js +22 -0
  31. package/dist/identity.test.js.map +1 -0
  32. package/dist/importer.d.ts +12 -0
  33. package/dist/importer.d.ts.map +1 -0
  34. package/dist/importer.js +297 -0
  35. package/dist/importer.js.map +1 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +92 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/index.test.d.ts +2 -0
  41. package/dist/index.test.d.ts.map +1 -0
  42. package/dist/index.test.js +770 -0
  43. package/dist/index.test.js.map +1 -0
  44. package/dist/memory/forget.d.ts +22 -0
  45. package/dist/memory/forget.d.ts.map +1 -0
  46. package/dist/memory/forget.js +84 -0
  47. package/dist/memory/forget.js.map +1 -0
  48. package/dist/memory/get.d.ts +36 -0
  49. package/dist/memory/get.d.ts.map +1 -0
  50. package/dist/memory/get.js +282 -0
  51. package/dist/memory/get.js.map +1 -0
  52. package/dist/memory/get.test.d.ts +2 -0
  53. package/dist/memory/get.test.d.ts.map +1 -0
  54. package/dist/memory/get.test.js +180 -0
  55. package/dist/memory/get.test.js.map +1 -0
  56. package/dist/memory/limits.d.ts +10 -0
  57. package/dist/memory/limits.d.ts.map +1 -0
  58. package/dist/memory/limits.js +18 -0
  59. package/dist/memory/limits.js.map +1 -0
  60. package/dist/memory/manager.d.ts +93 -0
  61. package/dist/memory/manager.d.ts.map +1 -0
  62. package/dist/memory/manager.js +344 -0
  63. package/dist/memory/manager.js.map +1 -0
  64. package/dist/memory/manager.test.d.ts +2 -0
  65. package/dist/memory/manager.test.d.ts.map +1 -0
  66. package/dist/memory/manager.test.js +201 -0
  67. package/dist/memory/manager.test.js.map +1 -0
  68. package/dist/memory/paths.d.ts +12 -0
  69. package/dist/memory/paths.d.ts.map +1 -0
  70. package/dist/memory/paths.js +31 -0
  71. package/dist/memory/paths.js.map +1 -0
  72. package/dist/memory/paths.test.d.ts +2 -0
  73. package/dist/memory/paths.test.d.ts.map +1 -0
  74. package/dist/memory/paths.test.js +35 -0
  75. package/dist/memory/paths.test.js.map +1 -0
  76. package/dist/memory/prompt.d.ts +37 -0
  77. package/dist/memory/prompt.d.ts.map +1 -0
  78. package/dist/memory/prompt.js +152 -0
  79. package/dist/memory/prompt.js.map +1 -0
  80. package/dist/memory/prompt.test.d.ts +2 -0
  81. package/dist/memory/prompt.test.d.ts.map +1 -0
  82. package/dist/memory/prompt.test.js +47 -0
  83. package/dist/memory/prompt.test.js.map +1 -0
  84. package/dist/memory/read-file-shared.d.ts +17 -0
  85. package/dist/memory/read-file-shared.d.ts.map +1 -0
  86. package/dist/memory/read-file-shared.js +53 -0
  87. package/dist/memory/read-file-shared.js.map +1 -0
  88. package/dist/memory/read-file-shared.test.d.ts +2 -0
  89. package/dist/memory/read-file-shared.test.d.ts.map +1 -0
  90. package/dist/memory/read-file-shared.test.js +82 -0
  91. package/dist/memory/read-file-shared.test.js.map +1 -0
  92. package/dist/memory/recall.d.ts +22 -0
  93. package/dist/memory/recall.d.ts.map +1 -0
  94. package/dist/memory/recall.js +58 -0
  95. package/dist/memory/recall.js.map +1 -0
  96. package/dist/memory/search.d.ts +30 -0
  97. package/dist/memory/search.d.ts.map +1 -0
  98. package/dist/memory/search.js +110 -0
  99. package/dist/memory/search.js.map +1 -0
  100. package/dist/memory/search.test.d.ts +2 -0
  101. package/dist/memory/search.test.d.ts.map +1 -0
  102. package/dist/memory/search.test.js +103 -0
  103. package/dist/memory/search.test.js.map +1 -0
  104. package/dist/memory/sessions-index-sync.d.ts +28 -0
  105. package/dist/memory/sessions-index-sync.d.ts.map +1 -0
  106. package/dist/memory/sessions-index-sync.js +253 -0
  107. package/dist/memory/sessions-index-sync.js.map +1 -0
  108. package/dist/memory/sessions-index-sync.test.d.ts +2 -0
  109. package/dist/memory/sessions-index-sync.test.d.ts.map +1 -0
  110. package/dist/memory/sessions-index-sync.test.js +280 -0
  111. package/dist/memory/sessions-index-sync.test.js.map +1 -0
  112. package/dist/memory/sessions-index.d.ts +30 -0
  113. package/dist/memory/sessions-index.d.ts.map +1 -0
  114. package/dist/memory/sessions-index.js +238 -0
  115. package/dist/memory/sessions-index.js.map +1 -0
  116. package/dist/memory/sessions-index.test.d.ts +2 -0
  117. package/dist/memory/sessions-index.test.d.ts.map +1 -0
  118. package/dist/memory/sessions-index.test.js +266 -0
  119. package/dist/memory/sessions-index.test.js.map +1 -0
  120. package/dist/memory/sessions-visibility.d.ts +18 -0
  121. package/dist/memory/sessions-visibility.d.ts.map +1 -0
  122. package/dist/memory/sessions-visibility.js +110 -0
  123. package/dist/memory/sessions-visibility.js.map +1 -0
  124. package/dist/memory/sessions-visibility.test.d.ts +2 -0
  125. package/dist/memory/sessions-visibility.test.d.ts.map +1 -0
  126. package/dist/memory/sessions-visibility.test.js +137 -0
  127. package/dist/memory/sessions-visibility.test.js.map +1 -0
  128. package/dist/memory/sessions.d.ts +26 -0
  129. package/dist/memory/sessions.d.ts.map +1 -0
  130. package/dist/memory/sessions.js +250 -0
  131. package/dist/memory/sessions.js.map +1 -0
  132. package/dist/memory/sessions.test.d.ts +2 -0
  133. package/dist/memory/sessions.test.d.ts.map +1 -0
  134. package/dist/memory/sessions.test.js +257 -0
  135. package/dist/memory/sessions.test.js.map +1 -0
  136. package/dist/memory/store.d.ts +25 -0
  137. package/dist/memory/store.d.ts.map +1 -0
  138. package/dist/memory/store.js +176 -0
  139. package/dist/memory/store.js.map +1 -0
  140. package/dist/migrations-fs.d.ts +5 -0
  141. package/dist/migrations-fs.d.ts.map +1 -0
  142. package/dist/migrations-fs.js +19 -0
  143. package/dist/migrations-fs.js.map +1 -0
  144. package/dist/migrations.d.ts +17 -0
  145. package/dist/migrations.d.ts.map +1 -0
  146. package/dist/migrations.js +44 -0
  147. package/dist/migrations.js.map +1 -0
  148. package/dist/migrations.test.d.ts +2 -0
  149. package/dist/migrations.test.d.ts.map +1 -0
  150. package/dist/migrations.test.js +66 -0
  151. package/dist/migrations.test.js.map +1 -0
  152. package/dist/plugin/capability.d.ts +7 -0
  153. package/dist/plugin/capability.d.ts.map +1 -0
  154. package/dist/plugin/capability.js +92 -0
  155. package/dist/plugin/capability.js.map +1 -0
  156. package/dist/plugin/capability.test.d.ts +2 -0
  157. package/dist/plugin/capability.test.d.ts.map +1 -0
  158. package/dist/plugin/capability.test.js +75 -0
  159. package/dist/plugin/capability.test.js.map +1 -0
  160. package/dist/plugin/lifecycle.d.ts +6 -0
  161. package/dist/plugin/lifecycle.d.ts.map +1 -0
  162. package/dist/plugin/lifecycle.js +31 -0
  163. package/dist/plugin/lifecycle.js.map +1 -0
  164. package/dist/plugin/prompt-cache.d.ts +10 -0
  165. package/dist/plugin/prompt-cache.d.ts.map +1 -0
  166. package/dist/plugin/prompt-cache.js +58 -0
  167. package/dist/plugin/prompt-cache.js.map +1 -0
  168. package/dist/plugin/runtime-context.d.ts +27 -0
  169. package/dist/plugin/runtime-context.d.ts.map +1 -0
  170. package/dist/plugin/runtime-context.js +91 -0
  171. package/dist/plugin/runtime-context.js.map +1 -0
  172. package/dist/plugin/runtime-helpers.d.ts +3 -0
  173. package/dist/plugin/runtime-helpers.d.ts.map +1 -0
  174. package/dist/plugin/runtime-helpers.js +12 -0
  175. package/dist/plugin/runtime-helpers.js.map +1 -0
  176. package/dist/plugin/session-delta-helpers.d.ts +11 -0
  177. package/dist/plugin/session-delta-helpers.d.ts.map +1 -0
  178. package/dist/plugin/session-delta-helpers.js +62 -0
  179. package/dist/plugin/session-delta-helpers.js.map +1 -0
  180. package/dist/plugin/session-delta.d.ts +12 -0
  181. package/dist/plugin/session-delta.d.ts.map +1 -0
  182. package/dist/plugin/session-delta.js +307 -0
  183. package/dist/plugin/session-delta.js.map +1 -0
  184. package/dist/plugin/tools/common.d.ts +7 -0
  185. package/dist/plugin/tools/common.d.ts.map +1 -0
  186. package/dist/plugin/tools/common.js +2 -0
  187. package/dist/plugin/tools/common.js.map +1 -0
  188. package/dist/plugin/tools/index.d.ts +3 -0
  189. package/dist/plugin/tools/index.d.ts.map +1 -0
  190. package/dist/plugin/tools/index.js +16 -0
  191. package/dist/plugin/tools/index.js.map +1 -0
  192. package/dist/plugin/tools/memory-forget.d.ts +3 -0
  193. package/dist/plugin/tools/memory-forget.d.ts.map +1 -0
  194. package/dist/plugin/tools/memory-forget.js +80 -0
  195. package/dist/plugin/tools/memory-forget.js.map +1 -0
  196. package/dist/plugin/tools/memory-forget.test.d.ts +2 -0
  197. package/dist/plugin/tools/memory-forget.test.d.ts.map +1 -0
  198. package/dist/plugin/tools/memory-forget.test.js +58 -0
  199. package/dist/plugin/tools/memory-forget.test.js.map +1 -0
  200. package/dist/plugin/tools/memory-get.d.ts +3 -0
  201. package/dist/plugin/tools/memory-get.d.ts.map +1 -0
  202. package/dist/plugin/tools/memory-get.js +136 -0
  203. package/dist/plugin/tools/memory-get.js.map +1 -0
  204. package/dist/plugin/tools/memory-recall.d.ts +3 -0
  205. package/dist/plugin/tools/memory-recall.d.ts.map +1 -0
  206. package/dist/plugin/tools/memory-recall.js +176 -0
  207. package/dist/plugin/tools/memory-recall.js.map +1 -0
  208. package/dist/plugin/tools/memory-recall.test.d.ts +2 -0
  209. package/dist/plugin/tools/memory-recall.test.d.ts.map +1 -0
  210. package/dist/plugin/tools/memory-recall.test.js +169 -0
  211. package/dist/plugin/tools/memory-recall.test.js.map +1 -0
  212. package/dist/plugin/tools/memory-search.d.ts +3 -0
  213. package/dist/plugin/tools/memory-search.d.ts.map +1 -0
  214. package/dist/plugin/tools/memory-search.js +332 -0
  215. package/dist/plugin/tools/memory-search.js.map +1 -0
  216. package/dist/plugin/tools/memory-search.test.d.ts +2 -0
  217. package/dist/plugin/tools/memory-search.test.d.ts.map +1 -0
  218. package/dist/plugin/tools/memory-search.test.js +205 -0
  219. package/dist/plugin/tools/memory-search.test.js.map +1 -0
  220. package/dist/plugin/tools/memory-status.d.ts +3 -0
  221. package/dist/plugin/tools/memory-status.d.ts.map +1 -0
  222. package/dist/plugin/tools/memory-status.js +134 -0
  223. package/dist/plugin/tools/memory-status.js.map +1 -0
  224. package/dist/plugin/tools/memory-store.d.ts +3 -0
  225. package/dist/plugin/tools/memory-store.d.ts.map +1 -0
  226. package/dist/plugin/tools/memory-store.js +88 -0
  227. package/dist/plugin/tools/memory-store.js.map +1 -0
  228. package/dist/plugin/tools/memory-store.test.d.ts +2 -0
  229. package/dist/plugin/tools/memory-store.test.d.ts.map +1 -0
  230. package/dist/plugin/tools/memory-store.test.js +64 -0
  231. package/dist/plugin/tools/memory-store.test.js.map +1 -0
  232. package/dist/plugin/tools/memory-visible-output.d.ts +20 -0
  233. package/dist/plugin/tools/memory-visible-output.d.ts.map +1 -0
  234. package/dist/plugin/tools/memory-visible-output.js +61 -0
  235. package/dist/plugin/tools/memory-visible-output.js.map +1 -0
  236. package/dist/plugin/types.d.ts +61 -0
  237. package/dist/plugin/types.d.ts.map +1 -0
  238. package/dist/plugin/types.js +2 -0
  239. package/dist/plugin/types.js.map +1 -0
  240. package/dist/postgres.d.ts +7 -0
  241. package/dist/postgres.d.ts.map +1 -0
  242. package/dist/postgres.js +55 -0
  243. package/dist/postgres.js.map +1 -0
  244. package/migrations/0001_init.sql +228 -0
  245. package/migrations/0002_session_index.sql +71 -0
  246. package/openclaw.plugin.json +314 -0
  247. package/package.json +63 -0
@@ -0,0 +1,238 @@
1
+ function clampInteger(value, min, max) {
2
+ if (!Number.isFinite(value)) {
3
+ return min;
4
+ }
5
+ const rounded = Math.floor(value);
6
+ return Math.min(max, Math.max(min, rounded));
7
+ }
8
+ function escapeLikePattern(value) {
9
+ return value
10
+ .replaceAll("\\", "\\\\")
11
+ .replaceAll("_", "\\_")
12
+ .replaceAll("%", "\\%");
13
+ }
14
+ export function normalizeSessionLookupPath(lookup) {
15
+ const trimmed = lookup.trim().replaceAll("\\", "/");
16
+ if (!trimmed.startsWith("sessions/")) {
17
+ return null;
18
+ }
19
+ const parts = trimmed.split("/").filter(Boolean);
20
+ if (parts.length !== 3) {
21
+ return null;
22
+ }
23
+ const [root, agentId, fileName] = parts;
24
+ if (root !== "sessions" || !agentId || !fileName) {
25
+ return null;
26
+ }
27
+ if (fileName === "." || fileName === ".." || fileName.includes("/") || fileName.includes("\\")) {
28
+ return null;
29
+ }
30
+ return `sessions/${agentId}/${fileName}`;
31
+ }
32
+ function buildAgentPathPrefix(agentId) {
33
+ return `sessions/${escapeLikePattern(agentId)}/%`;
34
+ }
35
+ function clampPositiveInteger(value, fallback) {
36
+ if (typeof value !== "number" || !Number.isFinite(value)) {
37
+ return fallback;
38
+ }
39
+ return Math.max(1, Math.floor(value));
40
+ }
41
+ function buildContinuationNotice(nextFrom) {
42
+ const base = typeof nextFrom === "number"
43
+ ? `[More content available. Use from=${nextFrom} to continue.]`
44
+ : "[More content available. Requested excerpt exceeded the default maxChars budget.]";
45
+ return `\n\n${base}`;
46
+ }
47
+ function buildIndexedSessionReadResult(params) {
48
+ const requestedFrom = clampPositiveInteger(params.from, 1);
49
+ const requestedLineCount = clampPositiveInteger(params.lines, params.defaultLines);
50
+ const requestedEndExclusive = requestedFrom + requestedLineCount;
51
+ const maxChars = Math.max(1, Math.floor(params.maxChars));
52
+ const sortedChunks = params.chunks
53
+ .filter((chunk) => Number.isFinite(chunk.startLine) && chunk.startLine > 0)
54
+ .slice()
55
+ .sort((left, right) => left.startLine - right.startLine);
56
+ if (sortedChunks.length === 0) {
57
+ return {
58
+ text: "",
59
+ path: params.relPath,
60
+ from: requestedFrom,
61
+ lines: 0,
62
+ };
63
+ }
64
+ const grouped = new Map();
65
+ for (const chunk of sortedChunks) {
66
+ const rendered = chunk.text ?? "";
67
+ const list = grouped.get(chunk.startLine) ?? [];
68
+ list.push(rendered);
69
+ grouped.set(chunk.startLine, list);
70
+ }
71
+ const sourceLines = Array.from(grouped.keys()).sort((left, right) => left - right);
72
+ const selectedSourceLines = sourceLines.filter((lineNo) => lineNo >= requestedFrom && lineNo < requestedEndExclusive);
73
+ if (selectedSourceLines.length === 0) {
74
+ return {
75
+ text: "",
76
+ path: params.relPath,
77
+ from: requestedFrom,
78
+ lines: 0,
79
+ };
80
+ }
81
+ const selectedRenderedLines = selectedSourceLines.flatMap((lineNo) => grouped.get(lineNo) ?? []);
82
+ const moreSourceLinesRemain = sourceLines.some((lineNo) => lineNo >= requestedEndExclusive);
83
+ let includedRenderedCount = selectedRenderedLines.length;
84
+ let text = selectedRenderedLines.join("\n");
85
+ while (includedRenderedCount > 1 && text.length > maxChars) {
86
+ includedRenderedCount -= 1;
87
+ text = selectedRenderedLines.slice(0, includedRenderedCount).join("\n");
88
+ }
89
+ let hardTruncatedSingleLine = false;
90
+ if (text.length > maxChars) {
91
+ text = text.slice(0, maxChars);
92
+ includedRenderedCount = 1;
93
+ hardTruncatedSingleLine = true;
94
+ }
95
+ let includedSourceLines = selectedSourceLines.length;
96
+ if (includedRenderedCount < selectedRenderedLines.length) {
97
+ let renderedSeen = 0;
98
+ includedSourceLines = 0;
99
+ for (const lineNo of selectedSourceLines) {
100
+ renderedSeen += (grouped.get(lineNo) ?? []).length;
101
+ if (renderedSeen > includedRenderedCount) {
102
+ break;
103
+ }
104
+ includedSourceLines += 1;
105
+ }
106
+ }
107
+ const truncated = hardTruncatedSingleLine || includedRenderedCount < selectedRenderedLines.length || moreSourceLinesRemain;
108
+ const nextLineAfterRange = sourceLines.find((lineNo) => lineNo >= requestedEndExclusive);
109
+ const nextLineWithinRange = selectedSourceLines[includedSourceLines];
110
+ const nextFrom = !hardTruncatedSingleLine && includedSourceLines > 0
111
+ ? nextLineWithinRange ?? nextLineAfterRange
112
+ : undefined;
113
+ return {
114
+ text: truncated && text ? `${text}${buildContinuationNotice(nextFrom)}` : text,
115
+ path: params.relPath,
116
+ from: selectedSourceLines[0] ?? requestedFrom,
117
+ lines: includedSourceLines,
118
+ ...(truncated ? { truncated: true } : {}),
119
+ ...(typeof nextFrom === "number" ? { nextFrom } : {}),
120
+ };
121
+ }
122
+ export async function memorySearchSessionsIndexDb(params) {
123
+ const q = params.query.trim();
124
+ if (!q) {
125
+ return [];
126
+ }
127
+ const limit = clampInteger(params.maxResults ?? params.limits.maxResults, 1, params.limits.maxResults);
128
+ const scopedByAgent = typeof params.currentAgentId === "string" && params.currentAgentId.trim().length > 0;
129
+ const result = await params.pool.query(scopedByAgent
130
+ ? `
131
+ SELECT
132
+ c.path,
133
+ LEFT(c.text, 240) AS snippet,
134
+ ts_rank_cd(c.search_vector, plainto_tsquery('simple', $3)) AS score,
135
+ c.start_line,
136
+ c.end_line,
137
+ f.updated_at
138
+ FROM session_index_chunks c
139
+ JOIN session_index_files f
140
+ ON f.id = c.file_id
141
+ WHERE c.user_id = $1
142
+ AND c.workspace_id = $2
143
+ AND c.search_vector @@ plainto_tsquery('simple', $3)
144
+ AND c.path LIKE $5
145
+ ORDER BY score DESC, f.updated_at DESC, c.path ASC, c.chunk_index ASC
146
+ LIMIT $4
147
+ `
148
+ : `
149
+ SELECT
150
+ c.path,
151
+ LEFT(c.text, 240) AS snippet,
152
+ ts_rank_cd(c.search_vector, plainto_tsquery('simple', $3)) AS score,
153
+ c.start_line,
154
+ c.end_line,
155
+ f.updated_at
156
+ FROM session_index_chunks c
157
+ JOIN session_index_files f
158
+ ON f.id = c.file_id
159
+ WHERE c.user_id = $1
160
+ AND c.workspace_id = $2
161
+ AND c.search_vector @@ plainto_tsquery('simple', $3)
162
+ ORDER BY score DESC, f.updated_at DESC, c.path ASC, c.chunk_index ASC
163
+ LIMIT $4
164
+ `, scopedByAgent
165
+ ? [params.userId, params.workspaceId, q, limit, buildAgentPathPrefix(params.currentAgentId.trim())]
166
+ : [params.userId, params.workspaceId, q, limit]);
167
+ return result.rows.map((row) => ({
168
+ corpus: "sessions",
169
+ path: row.path,
170
+ kind: "session",
171
+ score: Number.isFinite(row.score) ? row.score : 0,
172
+ snippet: row.snippet.length === 240 ? `${row.snippet}…` : row.snippet,
173
+ startLine: row.start_line,
174
+ endLine: row.end_line,
175
+ updatedAt: row.updated_at,
176
+ }));
177
+ }
178
+ export async function hasSessionsIndexRows(params) {
179
+ const scopedByAgent = typeof params.currentAgentId === "string" && params.currentAgentId.trim().length > 0;
180
+ const result = await params.pool.query(scopedByAgent
181
+ ? `
182
+ SELECT id
183
+ FROM session_index_files
184
+ WHERE user_id = $1
185
+ AND workspace_id = $2
186
+ AND path LIKE $3
187
+ LIMIT 1
188
+ `
189
+ : `
190
+ SELECT id
191
+ FROM session_index_files
192
+ WHERE user_id = $1
193
+ AND workspace_id = $2
194
+ LIMIT 1
195
+ `, scopedByAgent
196
+ ? [params.userId, params.workspaceId, buildAgentPathPrefix(params.currentAgentId.trim())]
197
+ : [params.userId, params.workspaceId]);
198
+ return result.rows.length > 0;
199
+ }
200
+ export async function memoryGetSessionFromIndexDb(params) {
201
+ const normalizedPath = normalizeSessionLookupPath(params.lookup);
202
+ if (!normalizedPath) {
203
+ return null;
204
+ }
205
+ const fileResult = await params.pool.query(`
206
+ SELECT id
207
+ FROM session_index_files
208
+ WHERE user_id = $1
209
+ AND workspace_id = $2
210
+ AND path = $3
211
+ LIMIT 1
212
+ `, [params.userId, params.workspaceId, normalizedPath]);
213
+ const fileRow = fileResult.rows[0];
214
+ if (!fileRow) {
215
+ return null;
216
+ }
217
+ const chunks = await params.pool.query(`
218
+ SELECT text, start_line
219
+ FROM session_index_chunks
220
+ WHERE file_id = $1
221
+ ORDER BY chunk_index ASC
222
+ `, [fileRow.id]);
223
+ if (chunks.rows.length === 0) {
224
+ return null;
225
+ }
226
+ return buildIndexedSessionReadResult({
227
+ chunks: chunks.rows.map((row) => ({
228
+ text: row.text,
229
+ startLine: row.start_line,
230
+ })),
231
+ relPath: normalizedPath,
232
+ from: params.fromLine,
233
+ lines: params.lineCount,
234
+ defaultLines: params.limits.getDefaultLines,
235
+ maxChars: params.limits.getMaxChars,
236
+ });
237
+ }
238
+ //# sourceMappingURL=sessions-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-index.js","sourceRoot":"","sources":["../../src/memory/sessions-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sessions-index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-index.test.d.ts","sourceRoot":"","sources":["../../src/memory/sessions-index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,266 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { hasSessionsIndexRows, memoryGetSessionFromIndexDb, memorySearchSessionsIndexDb, normalizeSessionLookupPath, } from "./sessions-index.js";
3
+ function createMockPool(rowsByCall) {
4
+ const calls = [];
5
+ const query = vi.fn(async (sql, args = []) => {
6
+ calls.push({ sql, args });
7
+ const rows = rowsByCall.shift() ?? [];
8
+ return { rows };
9
+ });
10
+ return { pool: { query }, calls, query };
11
+ }
12
+ describe("normalizeSessionLookupPath", () => {
13
+ it("normalizes valid sessions path and backslashes", () => {
14
+ expect(normalizeSessionLookupPath("sessions/main/a.jsonl")).toBe("sessions/main/a.jsonl");
15
+ expect(normalizeSessionLookupPath("sessions\\main\\a.jsonl")).toBe("sessions/main/a.jsonl");
16
+ });
17
+ it("rejects invalid or unsafe shapes", () => {
18
+ expect(normalizeSessionLookupPath("sessions/main")).toBeNull();
19
+ expect(normalizeSessionLookupPath("sessions/main/a/b.jsonl")).toBeNull();
20
+ expect(normalizeSessionLookupPath("sessions/main/..")).toBeNull();
21
+ expect(normalizeSessionLookupPath("db-memory/items/x.md")).toBeNull();
22
+ });
23
+ });
24
+ describe("hasSessionsIndexRows", () => {
25
+ it("returns true when at least one indexed file exists", async () => {
26
+ const { pool } = createMockPool([[{ id: "row-1" }]]);
27
+ const got = await hasSessionsIndexRows({
28
+ pool,
29
+ userId: "u1",
30
+ workspaceId: "w1",
31
+ });
32
+ expect(got).toBe(true);
33
+ });
34
+ it("returns false when no indexed files exist", async () => {
35
+ const { pool } = createMockPool([[]]);
36
+ const got = await hasSessionsIndexRows({
37
+ pool,
38
+ userId: "u1",
39
+ workspaceId: "w1",
40
+ });
41
+ expect(got).toBe(false);
42
+ });
43
+ it("applies current-agent path prefix when provided", async () => {
44
+ const { pool, calls } = createMockPool([[{ id: "row-1" }]]);
45
+ const got = await hasSessionsIndexRows({
46
+ pool,
47
+ userId: "u1",
48
+ workspaceId: "w1",
49
+ currentAgentId: "main",
50
+ });
51
+ expect(got).toBe(true);
52
+ expect(calls).toHaveLength(1);
53
+ expect(calls[0]?.sql).toContain("path LIKE $3");
54
+ expect(calls[0]?.args).toEqual(["u1", "w1", "sessions/main/%"]);
55
+ });
56
+ it("escapes wildcard characters in current-agent path prefix", async () => {
57
+ const { pool, calls } = createMockPool([[{ id: "row-1" }]]);
58
+ const got = await hasSessionsIndexRows({
59
+ pool,
60
+ userId: "u1",
61
+ workspaceId: "w1",
62
+ currentAgentId: "agent_a%prod",
63
+ });
64
+ expect(got).toBe(true);
65
+ expect(calls).toHaveLength(1);
66
+ expect(calls[0]?.args).toEqual(["u1", "w1", "sessions/agent\\_a\\%prod/%"]);
67
+ });
68
+ });
69
+ describe("memoryGetSessionFromIndexDb", () => {
70
+ it("returns null on index miss", async () => {
71
+ const { pool } = createMockPool([[]]);
72
+ const got = await memoryGetSessionFromIndexDb({
73
+ pool,
74
+ userId: "u1",
75
+ workspaceId: "w1",
76
+ lookup: "sessions/main/miss.jsonl",
77
+ limits: {
78
+ maxResults: 10,
79
+ getMaxChars: 12_000,
80
+ getDefaultLines: 120,
81
+ sessionsMaxFileBytes: 2_000_000,
82
+ sessionsWrapChars: 800,
83
+ },
84
+ });
85
+ expect(got).toBeNull();
86
+ });
87
+ it("returns bounded excerpt from indexed chunks", async () => {
88
+ const { pool } = createMockPool([
89
+ [{ id: "file-1" }],
90
+ [
91
+ { text: "User: hello", start_line: 3 },
92
+ { text: "Assistant: hi", start_line: 7 },
93
+ ],
94
+ ]);
95
+ const got = await memoryGetSessionFromIndexDb({
96
+ pool,
97
+ userId: "u1",
98
+ workspaceId: "w1",
99
+ lookup: "sessions/main/a.jsonl",
100
+ fromLine: 1,
101
+ lineCount: 50,
102
+ limits: {
103
+ maxResults: 10,
104
+ getMaxChars: 12_000,
105
+ getDefaultLines: 120,
106
+ sessionsMaxFileBytes: 2_000_000,
107
+ sessionsWrapChars: 800,
108
+ },
109
+ });
110
+ expect(got).not.toBeNull();
111
+ expect(got.path).toBe("sessions/main/a.jsonl");
112
+ expect(got.text).toContain("User: hello");
113
+ expect(got.text).toContain("Assistant: hi");
114
+ expect(got.from).toBe(3);
115
+ });
116
+ it("uses original session line numbers for fromLine/lineCount pagination", async () => {
117
+ const { pool } = createMockPool([
118
+ [{ id: "file-1" }],
119
+ [
120
+ { text: "User: very long", start_line: 3 },
121
+ { text: "continued", start_line: 3 },
122
+ { text: "Assistant: next", start_line: 7 },
123
+ ],
124
+ ]);
125
+ const got = await memoryGetSessionFromIndexDb({
126
+ pool,
127
+ userId: "u1",
128
+ workspaceId: "w1",
129
+ lookup: "sessions/main/a.jsonl",
130
+ fromLine: 3,
131
+ lineCount: 1,
132
+ limits: {
133
+ maxResults: 10,
134
+ getMaxChars: 12_000,
135
+ getDefaultLines: 120,
136
+ sessionsMaxFileBytes: 2_000_000,
137
+ sessionsWrapChars: 800,
138
+ },
139
+ });
140
+ expect(got).not.toBeNull();
141
+ expect(got.from).toBe(3);
142
+ expect(got.lines).toBe(1);
143
+ expect(got.text).toContain("User: very long");
144
+ expect(got.text).toContain("continued");
145
+ expect(got.text).not.toContain("Assistant: next");
146
+ expect(got.nextFrom).toBe(7);
147
+ });
148
+ it("applies strict numeric line range for sparse mapped lines", async () => {
149
+ const { pool } = createMockPool([
150
+ [{ id: "file-1" }],
151
+ [
152
+ { text: "line 10", start_line: 10 },
153
+ { text: "line 20", start_line: 20 },
154
+ { text: "line 30", start_line: 30 },
155
+ ],
156
+ ]);
157
+ const got = await memoryGetSessionFromIndexDb({
158
+ pool,
159
+ userId: "u1",
160
+ workspaceId: "w1",
161
+ lookup: "sessions/main/a.jsonl",
162
+ fromLine: 10,
163
+ lineCount: 5,
164
+ limits: {
165
+ maxResults: 10,
166
+ getMaxChars: 12_000,
167
+ getDefaultLines: 120,
168
+ sessionsMaxFileBytes: 2_000_000,
169
+ sessionsWrapChars: 800,
170
+ },
171
+ });
172
+ expect(got).not.toBeNull();
173
+ expect(got.from).toBe(10);
174
+ expect(got.lines).toBe(1);
175
+ expect(got.text).toContain("line 10");
176
+ expect(got.text).not.toContain("line 20");
177
+ expect(got.nextFrom).toBe(20);
178
+ });
179
+ });
180
+ describe("memorySearchSessionsIndexDb", () => {
181
+ it("maps DB rows to sessions hits", async () => {
182
+ const { pool, query } = createMockPool([
183
+ [
184
+ {
185
+ path: "sessions/main/a.jsonl",
186
+ snippet: "User: hello",
187
+ score: 0.42,
188
+ start_line: 3,
189
+ end_line: 3,
190
+ updated_at: "2026-05-13T00:00:00.000Z",
191
+ },
192
+ ],
193
+ ]);
194
+ const hits = await memorySearchSessionsIndexDb({
195
+ pool,
196
+ userId: "u1",
197
+ workspaceId: "w1",
198
+ limits: {
199
+ maxResults: 10,
200
+ getMaxChars: 12_000,
201
+ getDefaultLines: 120,
202
+ sessionsMaxFileBytes: 2_000_000,
203
+ sessionsWrapChars: 800,
204
+ },
205
+ query: "hello",
206
+ });
207
+ expect(query).toHaveBeenCalledTimes(1);
208
+ expect(hits).toHaveLength(1);
209
+ expect(hits[0]).toMatchObject({
210
+ corpus: "sessions",
211
+ path: "sessions/main/a.jsonl",
212
+ kind: "session",
213
+ score: 0.42,
214
+ startLine: 3,
215
+ endLine: 3,
216
+ });
217
+ });
218
+ it("scopes SQL by current agent path prefix when provided", async () => {
219
+ const { pool, calls } = createMockPool([[]]);
220
+ const hits = await memorySearchSessionsIndexDb({
221
+ pool,
222
+ userId: "u1",
223
+ workspaceId: "w1",
224
+ limits: {
225
+ maxResults: 10,
226
+ getMaxChars: 12_000,
227
+ getDefaultLines: 120,
228
+ sessionsMaxFileBytes: 2_000_000,
229
+ sessionsWrapChars: 800,
230
+ },
231
+ query: "hello",
232
+ currentAgentId: "main",
233
+ });
234
+ expect(hits).toHaveLength(0);
235
+ expect(calls).toHaveLength(1);
236
+ expect(calls[0]?.sql).toContain("AND c.path LIKE $5");
237
+ expect(calls[0]?.args).toEqual(["u1", "w1", "hello", 10, "sessions/main/%"]);
238
+ });
239
+ it("escapes wildcard characters in scoped sessions search prefix", async () => {
240
+ const { pool, calls } = createMockPool([[]]);
241
+ const hits = await memorySearchSessionsIndexDb({
242
+ pool,
243
+ userId: "u1",
244
+ workspaceId: "w1",
245
+ limits: {
246
+ maxResults: 10,
247
+ getMaxChars: 12_000,
248
+ getDefaultLines: 120,
249
+ sessionsMaxFileBytes: 2_000_000,
250
+ sessionsWrapChars: 800,
251
+ },
252
+ query: "hello",
253
+ currentAgentId: "agent_a%prod",
254
+ });
255
+ expect(hits).toHaveLength(0);
256
+ expect(calls).toHaveLength(1);
257
+ expect(calls[0]?.args).toEqual([
258
+ "u1",
259
+ "w1",
260
+ "hello",
261
+ 10,
262
+ "sessions/agent\\_a\\%prod/%",
263
+ ]);
264
+ });
265
+ });
266
+ //# sourceMappingURL=sessions-index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-index.test.js","sourceRoot":"","sources":["../../src/memory/sessions-index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAO7B,SAAS,cAAc,CAAC,UAA4B;IAClD,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,OAAkB,EAAE,EAAE,EAAE;QAC9D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAClD,CAAC;AAED,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC1F,MAAM,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,0BAA0B,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/D,MAAM,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzE,MAAM,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClE,MAAM,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC;YACrC,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC;YACrC,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC;YACrC,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,MAAM;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC;YACrC,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,cAAc;SAC/B,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,6BAA6B,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,2BAA2B,CAAC;YAC5C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,0BAA0B;YAClC,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC;YAC9B,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;YAClB;gBACE,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,EAAE;gBACtC,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,EAAE;aACzC;SACF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,2BAA2B,CAAC;YAC5C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,uBAAuB;YAC/B,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,EAAE;YACb,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAChD,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC;YAC9B,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;YAClB;gBACE,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC,EAAE;gBAC1C,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE;gBACpC,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC,EAAE;aAC3C;SACF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,2BAA2B,CAAC;YAC5C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,uBAAuB;YAC/B,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACnD,MAAM,CAAC,GAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC;YAC9B,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;YAClB;gBACE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnC,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnC,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE;aACpC;SACF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,2BAA2B,CAAC;YAC5C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,uBAAuB;YAC/B,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,CAAC;YACZ,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;YACrC;gBACE;oBACE,IAAI,EAAE,uBAAuB;oBAC7B,OAAO,EAAE,aAAa;oBACtB,KAAK,EAAE,IAAI;oBACX,UAAU,EAAE,CAAC;oBACb,QAAQ,EAAE,CAAC;oBACX,UAAU,EAAE,0BAA0B;iBACvC;aACF;SACF,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,2BAA2B,CAAC;YAC7C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;YACD,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;YAC5B,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,2BAA2B,CAAC;YAC7C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;YACD,KAAK,EAAE,OAAO;YACd,cAAc,EAAE,MAAM;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,2BAA2B,CAAC;YAC7C,IAAI;YACJ,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE;gBACN,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,MAAM;gBACnB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,SAAS;gBAC/B,iBAAiB,EAAE,GAAG;aACvB;YACD,KAAK,EAAE,OAAO;YACd,cAAc,EAAE,cAAc;SAC/B,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC;YAC7B,IAAI;YACJ,IAAI;YACJ,OAAO;YACP,EAAE;YACF,6BAA6B;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ type HitLike = {
2
+ path?: string;
3
+ corpus?: string;
4
+ source?: string;
5
+ };
6
+ export declare function filterSessionHitsByVisibility<T extends HitLike>(params: {
7
+ api: unknown;
8
+ hits: T[];
9
+ }): Promise<T[]>;
10
+ export declare function canAccessSessionPathByVisibility(params: {
11
+ api: unknown;
12
+ path: string;
13
+ }): Promise<{
14
+ allowed: boolean;
15
+ reason?: string;
16
+ }>;
17
+ export {};
18
+ //# sourceMappingURL=sessions-visibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions-visibility.d.ts","sourceRoot":"","sources":["../../src/memory/sessions-visibility.ts"],"names":[],"mappings":"AAWA,KAAK,OAAO,GAAG;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AA2EF,wBAAsB,6BAA6B,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE;IAC7E,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,CAAC,EAAE,CAAC;CACX,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAwBf;AAED,wBAAsB,gCAAgC,CAAC,MAAM,EAAE;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBjD"}
@@ -0,0 +1,110 @@
1
+ import { extractTranscriptIdentityFromSessionsMemoryHit, loadCombinedSessionStoreForGateway, resolveTranscriptStemToSessionKeys, } from "openclaw/plugin-sdk/session-transcript-hit";
2
+ import { createAgentToAgentPolicy, createSessionVisibilityGuard, resolveEffectiveSessionToolsVisibility, } from "openclaw/plugin-sdk/session-visibility";
3
+ function readRequesterSessionKey(api) {
4
+ const runtime = api?.runtime;
5
+ const value = runtime?.sessionKey;
6
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
7
+ }
8
+ function readRuntimeConfig(api) {
9
+ const current = api?.runtime?.config?.current;
10
+ if (typeof current === "function") {
11
+ const cfg = current();
12
+ if (cfg && typeof cfg === "object") {
13
+ return cfg;
14
+ }
15
+ }
16
+ return {};
17
+ }
18
+ function readRuntimeSandboxed(api) {
19
+ return api?.runtime?.sandboxed === true;
20
+ }
21
+ function isSessionsHit(hit) {
22
+ if ((hit.corpus ?? "").toLowerCase() === "sessions") {
23
+ return true;
24
+ }
25
+ if ((hit.source ?? "").toLowerCase() === "sessions") {
26
+ return true;
27
+ }
28
+ return typeof hit.path === "string" && hit.path.startsWith("sessions/");
29
+ }
30
+ async function createVisibilityGuard(api) {
31
+ const cfg = readRuntimeConfig(api);
32
+ const requesterSessionKey = readRequesterSessionKey(api);
33
+ const sandboxed = readRuntimeSandboxed(api);
34
+ const visibility = resolveEffectiveSessionToolsVisibility({
35
+ cfg: cfg,
36
+ sandboxed,
37
+ });
38
+ const a2aPolicy = createAgentToAgentPolicy(cfg);
39
+ const guard = requesterSessionKey
40
+ ? await createSessionVisibilityGuard({
41
+ action: "history",
42
+ requesterSessionKey,
43
+ visibility,
44
+ a2aPolicy,
45
+ })
46
+ : undefined;
47
+ const { store } = loadCombinedSessionStoreForGateway(cfg);
48
+ return { requesterSessionKey, guard: guard, combinedStore: (store ?? {}) };
49
+ }
50
+ function sessionKeysForHit(params) {
51
+ const identity = extractTranscriptIdentityFromSessionsMemoryHit(params.path);
52
+ if (!identity) {
53
+ return [];
54
+ }
55
+ return resolveTranscriptStemToSessionKeys({
56
+ store: params.combinedStore,
57
+ stem: identity.stem,
58
+ ...(identity.archived && identity.ownerAgentId
59
+ ? { archivedOwnerAgentId: identity.ownerAgentId }
60
+ : {}),
61
+ });
62
+ }
63
+ export async function filterSessionHitsByVisibility(params) {
64
+ const { requesterSessionKey, guard, combinedStore } = await createVisibilityGuard(params.api);
65
+ const next = [];
66
+ for (const hit of params.hits) {
67
+ if (!isSessionsHit(hit)) {
68
+ next.push(hit);
69
+ continue;
70
+ }
71
+ if (!requesterSessionKey || !guard || typeof hit.path !== "string") {
72
+ continue;
73
+ }
74
+ const keys = sessionKeysForHit({
75
+ combinedStore,
76
+ path: hit.path,
77
+ });
78
+ if (keys.length === 0) {
79
+ continue;
80
+ }
81
+ const allowed = keys.some((key) => guard.check(key).allowed);
82
+ if (allowed) {
83
+ next.push(hit);
84
+ }
85
+ }
86
+ return next;
87
+ }
88
+ export async function canAccessSessionPathByVisibility(params) {
89
+ const { requesterSessionKey, guard, combinedStore } = await createVisibilityGuard(params.api);
90
+ if (!requesterSessionKey || !guard) {
91
+ return { allowed: false, reason: "session visibility guard unavailable for current requester" };
92
+ }
93
+ const keys = sessionKeysForHit({
94
+ combinedStore,
95
+ path: params.path,
96
+ });
97
+ if (keys.length === 0) {
98
+ return { allowed: false, reason: "session transcript is not mapped to known session keys" };
99
+ }
100
+ let denyReason;
101
+ for (const key of keys) {
102
+ const verdict = guard.check(key);
103
+ if (verdict.allowed) {
104
+ return { allowed: true };
105
+ }
106
+ denyReason = denyReason ?? verdict.error;
107
+ }
108
+ return { allowed: false, ...(denyReason ? { reason: denyReason } : {}) };
109
+ }
110
+ //# sourceMappingURL=sessions-visibility.js.map