@chatcops/core 0.4.0 → 0.6.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 (243) hide show
  1. package/dist/agent/chat.d.ts +13 -0
  2. package/dist/agent/chat.d.ts.map +1 -0
  3. package/dist/agent/chat.js +42 -0
  4. package/dist/agent/chat.js.map +1 -0
  5. package/dist/agent/errors.d.ts +14 -0
  6. package/dist/agent/errors.d.ts.map +1 -0
  7. package/dist/agent/errors.js +24 -0
  8. package/dist/agent/errors.js.map +1 -0
  9. package/dist/agent/index.d.ts +5 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +5 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/run-turn.d.ts +79 -0
  14. package/dist/agent/run-turn.d.ts.map +1 -0
  15. package/dist/agent/run-turn.js +400 -0
  16. package/dist/agent/run-turn.js.map +1 -0
  17. package/dist/agent/tool-registry.d.ts +30 -0
  18. package/dist/agent/tool-registry.d.ts.map +1 -0
  19. package/dist/agent/tool-registry.js +66 -0
  20. package/dist/agent/tool-registry.js.map +1 -0
  21. package/dist/analytics/collector.d.ts +2 -0
  22. package/dist/analytics/collector.d.ts.map +1 -1
  23. package/dist/analytics/collector.js +16 -10
  24. package/dist/analytics/collector.js.map +1 -1
  25. package/dist/analytics/index.d.ts +2 -0
  26. package/dist/analytics/index.d.ts.map +1 -1
  27. package/dist/analytics/index.js +2 -0
  28. package/dist/analytics/index.js.map +1 -1
  29. package/dist/analytics/names.d.ts +21 -0
  30. package/dist/analytics/names.d.ts.map +1 -0
  31. package/dist/analytics/names.js +41 -0
  32. package/dist/analytics/names.js.map +1 -0
  33. package/dist/analytics/sink.d.ts +27 -0
  34. package/dist/analytics/sink.d.ts.map +1 -0
  35. package/dist/analytics/sink.js +109 -0
  36. package/dist/analytics/sink.js.map +1 -0
  37. package/dist/conversation/index.d.ts +1 -0
  38. package/dist/conversation/index.d.ts.map +1 -1
  39. package/dist/conversation/index.js.map +1 -1
  40. package/dist/conversation/manager.d.ts +65 -6
  41. package/dist/conversation/manager.d.ts.map +1 -1
  42. package/dist/conversation/manager.js +110 -34
  43. package/dist/conversation/manager.js.map +1 -1
  44. package/dist/conversation/store.d.ts +6 -5
  45. package/dist/conversation/store.d.ts.map +1 -1
  46. package/dist/conversation/store.js +4 -0
  47. package/dist/conversation/store.js.map +1 -1
  48. package/dist/index.d.ts +21 -4
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +16 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/knowledge/base.d.ts +8 -0
  53. package/dist/knowledge/base.d.ts.map +1 -1
  54. package/dist/knowledge/tokenize.d.ts.map +1 -1
  55. package/dist/knowledge/tokenize.js +4 -4
  56. package/dist/knowledge/tokenize.js.map +1 -1
  57. package/dist/limits/budget.d.ts +84 -0
  58. package/dist/limits/budget.d.ts.map +1 -0
  59. package/dist/limits/budget.js +114 -0
  60. package/dist/limits/budget.js.map +1 -0
  61. package/dist/limits/rate-limit.d.ts +53 -0
  62. package/dist/limits/rate-limit.d.ts.map +1 -0
  63. package/dist/limits/rate-limit.js +68 -0
  64. package/dist/limits/rate-limit.js.map +1 -0
  65. package/dist/logger.d.ts +36 -0
  66. package/dist/logger.d.ts.map +1 -0
  67. package/dist/logger.js +40 -0
  68. package/dist/logger.js.map +1 -0
  69. package/dist/parts.d.ts +9 -0
  70. package/dist/parts.d.ts.map +1 -0
  71. package/dist/parts.js +17 -0
  72. package/dist/parts.js.map +1 -0
  73. package/dist/protocol/ai-sdk.d.ts +27 -0
  74. package/dist/protocol/ai-sdk.d.ts.map +1 -0
  75. package/dist/protocol/ai-sdk.js +127 -0
  76. package/dist/protocol/ai-sdk.js.map +1 -0
  77. package/dist/protocol/errors.d.ts +10 -0
  78. package/dist/protocol/errors.d.ts.map +1 -0
  79. package/dist/protocol/errors.js +42 -0
  80. package/dist/protocol/errors.js.map +1 -0
  81. package/dist/protocol/index.d.ts +9 -0
  82. package/dist/protocol/index.d.ts.map +1 -0
  83. package/dist/protocol/index.js +6 -0
  84. package/dist/protocol/index.js.map +1 -0
  85. package/dist/protocol/legacy.d.ts +18 -0
  86. package/dist/protocol/legacy.d.ts.map +1 -0
  87. package/dist/protocol/legacy.js +41 -0
  88. package/dist/protocol/legacy.js.map +1 -0
  89. package/dist/protocol/sse.d.ts +10 -0
  90. package/dist/protocol/sse.d.ts.map +1 -0
  91. package/dist/protocol/sse.js +15 -0
  92. package/dist/protocol/sse.js.map +1 -0
  93. package/dist/protocol/v1.d.ts +140 -0
  94. package/dist/protocol/v1.d.ts.map +1 -0
  95. package/dist/protocol/v1.js +15 -0
  96. package/dist/protocol/v1.js.map +1 -0
  97. package/dist/providers/base.d.ts +13 -28
  98. package/dist/providers/base.d.ts.map +1 -1
  99. package/dist/providers/base.js +36 -47
  100. package/dist/providers/base.js.map +1 -1
  101. package/dist/providers/claude.d.ts +41 -6
  102. package/dist/providers/claude.d.ts.map +1 -1
  103. package/dist/providers/claude.js +223 -96
  104. package/dist/providers/claude.js.map +1 -1
  105. package/dist/providers/gemini.d.ts +18 -3
  106. package/dist/providers/gemini.d.ts.map +1 -1
  107. package/dist/providers/gemini.js +208 -91
  108. package/dist/providers/gemini.js.map +1 -1
  109. package/dist/providers/history.d.ts +52 -0
  110. package/dist/providers/history.d.ts.map +1 -0
  111. package/dist/providers/history.js +212 -0
  112. package/dist/providers/history.js.map +1 -0
  113. package/dist/providers/index.d.ts +5 -5
  114. package/dist/providers/index.d.ts.map +1 -1
  115. package/dist/providers/index.js +5 -4
  116. package/dist/providers/index.js.map +1 -1
  117. package/dist/providers/openai.d.ts +28 -6
  118. package/dist/providers/openai.d.ts.map +1 -1
  119. package/dist/providers/openai.js +213 -113
  120. package/dist/providers/openai.js.map +1 -1
  121. package/dist/providers/registry.d.ts +7 -0
  122. package/dist/providers/registry.d.ts.map +1 -0
  123. package/dist/providers/registry.js +12 -0
  124. package/dist/providers/registry.js.map +1 -0
  125. package/dist/providers/schema.d.ts +16 -0
  126. package/dist/providers/schema.d.ts.map +1 -0
  127. package/dist/providers/schema.js +80 -0
  128. package/dist/providers/schema.js.map +1 -0
  129. package/dist/providers/tool-execution.d.ts +13 -0
  130. package/dist/providers/tool-execution.d.ts.map +1 -1
  131. package/dist/providers/tool-execution.js +49 -13
  132. package/dist/providers/tool-execution.js.map +1 -1
  133. package/dist/providers/types.d.ts +89 -0
  134. package/dist/providers/types.d.ts.map +1 -0
  135. package/dist/providers/types.js +2 -0
  136. package/dist/providers/types.js.map +1 -0
  137. package/dist/retrieval/citations.d.ts +44 -0
  138. package/dist/retrieval/citations.d.ts.map +1 -0
  139. package/dist/retrieval/citations.js +97 -0
  140. package/dist/retrieval/citations.js.map +1 -0
  141. package/dist/retrieval/cohere-reranker.d.ts +13 -0
  142. package/dist/retrieval/cohere-reranker.d.ts.map +1 -0
  143. package/dist/retrieval/cohere-reranker.js +33 -0
  144. package/dist/retrieval/cohere-reranker.js.map +1 -0
  145. package/dist/retrieval/gemini-embedder.d.ts +26 -0
  146. package/dist/retrieval/gemini-embedder.d.ts.map +1 -0
  147. package/dist/retrieval/gemini-embedder.js +36 -0
  148. package/dist/retrieval/gemini-embedder.js.map +1 -0
  149. package/dist/retrieval/http.d.ts +20 -0
  150. package/dist/retrieval/http.d.ts.map +1 -0
  151. package/dist/retrieval/http.js +68 -0
  152. package/dist/retrieval/http.js.map +1 -0
  153. package/dist/retrieval/index.d.ts +14 -0
  154. package/dist/retrieval/index.d.ts.map +1 -0
  155. package/dist/retrieval/index.js +13 -0
  156. package/dist/retrieval/index.js.map +1 -0
  157. package/dist/retrieval/knowledge.d.ts +16 -0
  158. package/dist/retrieval/knowledge.d.ts.map +1 -0
  159. package/dist/retrieval/knowledge.js +21 -0
  160. package/dist/retrieval/knowledge.js.map +1 -0
  161. package/dist/retrieval/openai-embedder.d.ts +25 -0
  162. package/dist/retrieval/openai-embedder.d.ts.map +1 -0
  163. package/dist/retrieval/openai-embedder.js +30 -0
  164. package/dist/retrieval/openai-embedder.js.map +1 -0
  165. package/dist/retrieval/query.d.ts +8 -0
  166. package/dist/retrieval/query.d.ts.map +1 -0
  167. package/dist/retrieval/query.js +19 -0
  168. package/dist/retrieval/query.js.map +1 -0
  169. package/dist/retrieval/retrievers.d.ts +30 -0
  170. package/dist/retrieval/retrievers.d.ts.map +1 -0
  171. package/dist/retrieval/retrievers.js +89 -0
  172. package/dist/retrieval/retrievers.js.map +1 -0
  173. package/dist/retrieval/sources.d.ts +16 -0
  174. package/dist/retrieval/sources.d.ts.map +1 -0
  175. package/dist/retrieval/sources.js +37 -0
  176. package/dist/retrieval/sources.js.map +1 -0
  177. package/dist/retrieval/types.d.ts +50 -0
  178. package/dist/retrieval/types.d.ts.map +1 -0
  179. package/dist/retrieval/types.js +2 -0
  180. package/dist/retrieval/types.js.map +1 -0
  181. package/dist/retrieval/voyage-embedder.d.ts +33 -0
  182. package/dist/retrieval/voyage-embedder.d.ts.map +1 -0
  183. package/dist/retrieval/voyage-embedder.js +33 -0
  184. package/dist/retrieval/voyage-embedder.js.map +1 -0
  185. package/dist/retrieval/voyage-reranker.d.ts +13 -0
  186. package/dist/retrieval/voyage-reranker.d.ts.map +1 -0
  187. package/dist/retrieval/voyage-reranker.js +38 -0
  188. package/dist/retrieval/voyage-reranker.js.map +1 -0
  189. package/dist/retrieval/workers-ai-embedder.d.ts +21 -0
  190. package/dist/retrieval/workers-ai-embedder.d.ts.map +1 -0
  191. package/dist/retrieval/workers-ai-embedder.js +42 -0
  192. package/dist/retrieval/workers-ai-embedder.js.map +1 -0
  193. package/dist/retrieval/workers-ai-reranker.d.ts +11 -0
  194. package/dist/retrieval/workers-ai-reranker.d.ts.map +1 -0
  195. package/dist/retrieval/workers-ai-reranker.js +54 -0
  196. package/dist/retrieval/workers-ai-reranker.js.map +1 -0
  197. package/dist/storage/adapt.d.ts +15 -0
  198. package/dist/storage/adapt.d.ts.map +1 -0
  199. package/dist/storage/adapt.js +83 -0
  200. package/dist/storage/adapt.js.map +1 -0
  201. package/dist/storage/errors.d.ts +18 -0
  202. package/dist/storage/errors.d.ts.map +1 -0
  203. package/dist/storage/errors.js +28 -0
  204. package/dist/storage/errors.js.map +1 -0
  205. package/dist/storage/index.d.ts +6 -0
  206. package/dist/storage/index.d.ts.map +1 -0
  207. package/dist/storage/index.js +5 -0
  208. package/dist/storage/index.js.map +1 -0
  209. package/dist/storage/memory-vectors.d.ts +22 -0
  210. package/dist/storage/memory-vectors.d.ts.map +1 -0
  211. package/dist/storage/memory-vectors.js +140 -0
  212. package/dist/storage/memory-vectors.js.map +1 -0
  213. package/dist/storage/memory.d.ts +24 -0
  214. package/dist/storage/memory.d.ts.map +1 -0
  215. package/dist/storage/memory.js +265 -0
  216. package/dist/storage/memory.js.map +1 -0
  217. package/dist/storage/types.d.ts +188 -0
  218. package/dist/storage/types.d.ts.map +1 -0
  219. package/dist/storage/types.js +2 -0
  220. package/dist/storage/types.js.map +1 -0
  221. package/dist/testing/conformance.d.ts +30 -0
  222. package/dist/testing/conformance.d.ts.map +1 -0
  223. package/dist/testing/conformance.js +505 -0
  224. package/dist/testing/conformance.js.map +1 -0
  225. package/dist/testing/index.d.ts +3 -0
  226. package/dist/testing/index.d.ts.map +1 -0
  227. package/dist/testing/index.js +5 -0
  228. package/dist/testing/index.js.map +1 -0
  229. package/dist/testing/provider.d.ts +47 -0
  230. package/dist/testing/provider.d.ts.map +1 -0
  231. package/dist/testing/provider.js +83 -0
  232. package/dist/testing/provider.js.map +1 -0
  233. package/dist/tools/base.d.ts +14 -4
  234. package/dist/tools/base.d.ts.map +1 -1
  235. package/dist/tools/base.js +4 -2
  236. package/dist/tools/base.js.map +1 -1
  237. package/dist/tools/lead-capture.d.ts +4 -2
  238. package/dist/tools/lead-capture.d.ts.map +1 -1
  239. package/dist/tools/lead-capture.js +7 -2
  240. package/dist/tools/lead-capture.js.map +1 -1
  241. package/dist/types.d.ts +146 -7
  242. package/dist/types.d.ts.map +1 -1
  243. package/package.json +51 -3
@@ -0,0 +1,265 @@
1
+ import { ConflictError } from './errors.js';
2
+ const DAY_MS = 24 * 60 * 60 * 1000;
3
+ const HOUR_MS = 60 * 60 * 1000;
4
+ /**
5
+ * Keeps everything in this process. Fine for local development and a single
6
+ * long-running server; on serverless each instance has its own copy, so
7
+ * conversations and limits don't carry over between requests.
8
+ *
9
+ * Every capability is bounded, and nothing runs on a timer: expired entries
10
+ * are dropped when they're next read or when a map reaches its cap. Objects
11
+ * are copied in and out, so callers can't change stored data by accident.
12
+ */
13
+ export function memoryStorage(options = {}) {
14
+ const now = options.now ?? Date.now;
15
+ return {
16
+ conversations: new MemoryConversationStore(options.maxConversations ?? 1000, options.conversationTtlMs ?? 7 * DAY_MS, now),
17
+ counters: new MemoryCounterStore(options.maxKeys ?? 10_000, now),
18
+ kv: new MemoryKeyValueStore(options.maxKeys ?? 10_000, now),
19
+ events: new MemoryEventSink(options.maxEvents ?? 10_000),
20
+ };
21
+ }
22
+ class MemoryConversationStore {
23
+ maxConversations;
24
+ ttlMs;
25
+ now;
26
+ records = new Map();
27
+ constructor(maxConversations, ttlMs, now) {
28
+ this.maxConversations = maxConversations;
29
+ this.ttlMs = ttlMs;
30
+ this.now = now;
31
+ }
32
+ async get(id) {
33
+ const record = this.read(id);
34
+ return record ? structuredClone(record) : null;
35
+ }
36
+ async save(conversation) {
37
+ const current = this.read(conversation.id);
38
+ this.write({
39
+ ...structuredClone(conversation),
40
+ version: (current?.version ?? 0) + 1,
41
+ updatedAt: this.now(),
42
+ });
43
+ }
44
+ async delete(id) {
45
+ this.records.delete(id);
46
+ }
47
+ async append(id, messages, options = {}) {
48
+ const current = this.read(id);
49
+ const version = current?.version ?? 0;
50
+ if (options.expectedVersion !== undefined && options.expectedVersion !== version) {
51
+ throw new ConflictError(id, options.expectedVersion, version);
52
+ }
53
+ const time = this.now();
54
+ const metadata = options.metadata || current?.metadata ? { ...current?.metadata, ...structuredClone(options.metadata) } : undefined;
55
+ this.write({
56
+ id,
57
+ messages: [...(current?.messages ?? []), ...structuredClone(messages)],
58
+ ...(metadata ? { metadata } : {}),
59
+ version: version + 1,
60
+ createdAt: current?.createdAt ?? time,
61
+ updatedAt: time,
62
+ });
63
+ return { version: version + 1 };
64
+ }
65
+ async updateMessage(id, message) {
66
+ const current = this.read(id);
67
+ const index = current?.messages.findIndex((m) => m.id === message.id) ?? -1;
68
+ if (!current || index === -1)
69
+ return false;
70
+ const messages = [...current.messages];
71
+ messages[index] = structuredClone(message);
72
+ this.write({ ...current, messages, version: (current.version ?? 0) + 1, updatedAt: this.now() });
73
+ return true;
74
+ }
75
+ async removeMessage(id, messageId) {
76
+ const current = this.read(id);
77
+ if (!current?.messages.some((m) => m.id === messageId))
78
+ return false;
79
+ this.write({
80
+ ...current,
81
+ messages: current.messages.filter((m) => m.id !== messageId),
82
+ version: (current.version ?? 0) + 1,
83
+ updatedAt: this.now(),
84
+ });
85
+ return true;
86
+ }
87
+ async list(query) {
88
+ const all = [...this.records.values()]
89
+ .filter((c) => !this.expired(c))
90
+ .filter((c) => query.updatedAfter === undefined || c.updatedAt > query.updatedAfter)
91
+ .sort((a, b) => b.updatedAt - a.updatedAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
92
+ let start = 0;
93
+ if (query.cursor) {
94
+ const index = all.findIndex((c) => cursorOf(c) === query.cursor);
95
+ start = index === -1 ? all.length : index + 1;
96
+ }
97
+ const page = all.slice(start, start + query.limit);
98
+ const items = page.map((c) => ({
99
+ id: c.id,
100
+ createdAt: c.createdAt,
101
+ updatedAt: c.updatedAt,
102
+ messageCount: c.messages.length,
103
+ ...(c.metadata ? { metadata: structuredClone(c.metadata) } : {}),
104
+ }));
105
+ const last = page.at(-1);
106
+ return start + page.length < all.length && last ? { items, cursor: cursorOf(last) } : { items };
107
+ }
108
+ async purge(before) {
109
+ let removed = 0;
110
+ for (const [id, conversation] of this.records) {
111
+ if (conversation.updatedAt < before) {
112
+ this.records.delete(id);
113
+ removed++;
114
+ }
115
+ }
116
+ return removed;
117
+ }
118
+ /** Returns the live record (not a copy) and marks it as recently used. */
119
+ read(id) {
120
+ const record = this.records.get(id);
121
+ if (!record)
122
+ return undefined;
123
+ if (this.expired(record)) {
124
+ this.records.delete(id);
125
+ return undefined;
126
+ }
127
+ this.records.delete(id);
128
+ this.records.set(id, record);
129
+ return record;
130
+ }
131
+ write(conversation) {
132
+ this.records.delete(conversation.id);
133
+ this.records.set(conversation.id, conversation);
134
+ while (this.records.size > this.maxConversations) {
135
+ const oldest = this.records.keys().next().value;
136
+ if (oldest === undefined)
137
+ break;
138
+ this.records.delete(oldest);
139
+ }
140
+ }
141
+ expired(conversation) {
142
+ return this.now() - conversation.updatedAt > this.ttlMs;
143
+ }
144
+ }
145
+ function cursorOf(conversation) {
146
+ return `${conversation.updatedAt}:${conversation.id}`;
147
+ }
148
+ /** A map whose entries expire, swept when it reaches its cap. */
149
+ class ExpiringMap {
150
+ maxKeys;
151
+ now;
152
+ entries = new Map();
153
+ constructor(maxKeys, now) {
154
+ this.maxKeys = maxKeys;
155
+ this.now = now;
156
+ }
157
+ get(key) {
158
+ const entry = this.entries.get(key);
159
+ if (entry && entry.expiresAt <= this.now()) {
160
+ this.entries.delete(key);
161
+ return undefined;
162
+ }
163
+ return entry;
164
+ }
165
+ set(key, entry) {
166
+ this.entries.delete(key);
167
+ this.entries.set(key, entry);
168
+ if (this.entries.size <= this.maxKeys)
169
+ return;
170
+ const time = this.now();
171
+ for (const [k, e] of this.entries) {
172
+ if (e.expiresAt <= time)
173
+ this.entries.delete(k);
174
+ }
175
+ while (this.entries.size > this.maxKeys) {
176
+ const oldest = this.entries.keys().next().value;
177
+ if (oldest === undefined)
178
+ break;
179
+ this.entries.delete(oldest);
180
+ }
181
+ }
182
+ delete(key) {
183
+ this.entries.delete(key);
184
+ }
185
+ }
186
+ class MemoryCounterStore {
187
+ now;
188
+ counters;
189
+ constructor(maxKeys, now) {
190
+ this.now = now;
191
+ this.counters = new ExpiringMap(maxKeys, now);
192
+ }
193
+ async increment(key, by, ttlMs) {
194
+ const current = this.counters.get(key);
195
+ const entry = current
196
+ ? { value: current.value + by, expiresAt: current.expiresAt }
197
+ : { value: by, expiresAt: this.now() + ttlMs };
198
+ this.counters.set(key, entry);
199
+ return { ...entry };
200
+ }
201
+ async get(key) {
202
+ const entry = this.counters.get(key);
203
+ return entry ? { ...entry } : null;
204
+ }
205
+ }
206
+ const NO_EXPIRY = Number.POSITIVE_INFINITY;
207
+ class MemoryKeyValueStore {
208
+ now;
209
+ values;
210
+ constructor(maxKeys, now) {
211
+ this.now = now;
212
+ this.values = new ExpiringMap(maxKeys, now);
213
+ }
214
+ async get(key) {
215
+ const entry = this.values.get(key);
216
+ return entry ? structuredClone(entry.value) : null;
217
+ }
218
+ async set(key, value, options = {}) {
219
+ this.values.set(key, { value: structuredClone(value), expiresAt: this.expiry(options.ttlMs) });
220
+ }
221
+ async setIfAbsent(key, value, options = {}) {
222
+ if (this.values.get(key))
223
+ return false;
224
+ this.values.set(key, { value: structuredClone(value), expiresAt: this.expiry(options.ttlMs) });
225
+ return true;
226
+ }
227
+ async delete(key) {
228
+ this.values.delete(key);
229
+ }
230
+ expiry(ttlMs) {
231
+ return ttlMs === undefined ? NO_EXPIRY : this.now() + ttlMs;
232
+ }
233
+ }
234
+ class MemoryEventSink {
235
+ maxEvents;
236
+ events = [];
237
+ constructor(maxEvents) {
238
+ this.maxEvents = maxEvents;
239
+ }
240
+ async write(events) {
241
+ this.events.push(...structuredClone(events));
242
+ if (this.events.length > this.maxEvents) {
243
+ this.events = this.events.slice(-this.maxEvents);
244
+ }
245
+ }
246
+ async query(query) {
247
+ const size = query.groupBy === 'hour' ? HOUR_MS : DAY_MS;
248
+ const counts = new Map();
249
+ for (const event of this.events) {
250
+ if (event.timestamp < query.from || event.timestamp >= query.to)
251
+ continue;
252
+ if (query.type && event.type !== query.type)
253
+ continue;
254
+ const bucket = Math.floor(event.timestamp / size) * size;
255
+ const key = `${bucket}:${event.type}`;
256
+ const count = counts.get(key);
257
+ if (count)
258
+ count.count++;
259
+ else
260
+ counts.set(key, { bucket, type: event.type, count: 1 });
261
+ }
262
+ return [...counts.values()].sort((a, b) => a.bucket - b.bucket || (a.type < b.type ? -1 : 1));
263
+ }
264
+ }
265
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import type { AnalyticsEvent, ChatMessage, Conversation } from '../types.js';
2
+ export interface AppendOptions {
3
+ /**
4
+ * The version the caller last read. When the stored conversation has moved
5
+ * on, the append fails with a `ConflictError` and writes nothing. A
6
+ * conversation that doesn't exist yet is at version 0.
7
+ */
8
+ expectedVersion?: number;
9
+ /** Merged into the conversation's metadata (shallow, new keys win). */
10
+ metadata?: Record<string, unknown>;
11
+ }
12
+ export interface ConversationSummary {
13
+ id: string;
14
+ createdAt: number;
15
+ updatedAt: number;
16
+ messageCount: number;
17
+ metadata?: Record<string, unknown>;
18
+ }
19
+ export interface ListQuery {
20
+ limit: number;
21
+ /** From the previous page's `cursor`. */
22
+ cursor?: string;
23
+ /** Only conversations updated after this time (ms). */
24
+ updatedAfter?: number;
25
+ }
26
+ /**
27
+ * Where conversations live.
28
+ *
29
+ * `get`, `save` and `delete` are the 0.4 interface and still all a store
30
+ * needs. A store that also has `append` lets two server instances write to the
31
+ * same conversation without losing messages; without it the server reads,
32
+ * changes and writes back the whole conversation, and warns once.
33
+ */
34
+ export interface ConversationStore {
35
+ get(id: string): Promise<Conversation | null>;
36
+ /** Replaces the whole conversation. */
37
+ save(conversation: Conversation): Promise<void>;
38
+ delete(id: string): Promise<void>;
39
+ /**
40
+ * Adds messages at the end, creating the conversation when it doesn't
41
+ * exist, and returns the new version. Atomic: concurrent appends never
42
+ * lose a message.
43
+ */
44
+ append?(id: string, messages: ChatMessage[], options?: AppendOptions): Promise<{
45
+ version: number;
46
+ }>;
47
+ /** Replaces the message with the same id. Resolves `false` when there is none. */
48
+ updateMessage?(id: string, message: ChatMessage): Promise<boolean>;
49
+ /** Resolves `false` when there is no such message. */
50
+ removeMessage?(id: string, messageId: string): Promise<boolean>;
51
+ /** Most recently updated first. */
52
+ list?(query: ListQuery): Promise<{
53
+ items: ConversationSummary[];
54
+ cursor?: string;
55
+ }>;
56
+ /** Deletes conversations last updated before `before` (ms) and returns how many. */
57
+ purge?(before: number): Promise<number>;
58
+ }
59
+ export interface CounterValue {
60
+ value: number;
61
+ /** When the counter resets (ms). */
62
+ expiresAt: number;
63
+ }
64
+ /**
65
+ * Atomic counters that reset after a while. Rate limits and token budgets
66
+ * are built on this, so it has to be exact under concurrent requests.
67
+ */
68
+ export interface CounterStore {
69
+ /**
70
+ * Adds `by` and returns the new value. A missing or expired counter starts
71
+ * from zero and expires `ttlMs` from now; later increments keep that expiry.
72
+ */
73
+ increment(key: string, by: number, ttlMs: number): Promise<CounterValue>;
74
+ get(key: string): Promise<CounterValue | null>;
75
+ }
76
+ export interface KeyValueStore {
77
+ get<T = unknown>(key: string): Promise<T | null>;
78
+ set(key: string, value: unknown, options?: {
79
+ ttlMs?: number;
80
+ }): Promise<void>;
81
+ /** Sets the value only when the key is missing or expired. Resolves whether it did. */
82
+ setIfAbsent?(key: string, value: unknown, options?: {
83
+ ttlMs?: number;
84
+ }): Promise<boolean>;
85
+ delete(key: string): Promise<void>;
86
+ }
87
+ export interface EventQuery {
88
+ type?: string;
89
+ /** Start time (ms), inclusive. */
90
+ from: number;
91
+ /** End time (ms), exclusive. */
92
+ to: number;
93
+ groupBy?: 'day' | 'hour';
94
+ }
95
+ export interface EventCount {
96
+ /** Start of the bucket (ms, UTC). */
97
+ bucket: number;
98
+ type: string;
99
+ count: number;
100
+ }
101
+ export interface EventSink {
102
+ write(events: AnalyticsEvent[]): Promise<void>;
103
+ query?(query: EventQuery): Promise<EventCount[]>;
104
+ }
105
+ export type MetadataValue = string | number | boolean;
106
+ /**
107
+ * Which records a search may return. Every key has to match: a value matches
108
+ * a record whose metadata has exactly that value (same type), and an array
109
+ * matches any of its values. A record without the key never matches.
110
+ *
111
+ * ```ts
112
+ * { locale: 'de', collection: ['docs', 'pricing'] }
113
+ * ```
114
+ */
115
+ export type MetadataFilter = Record<string, MetadataValue | MetadataValue[]>;
116
+ /** The page or document a chunk came from. */
117
+ export interface VectorSource {
118
+ /** Groups a page's chunks, so they can be replaced or removed together. */
119
+ id: string;
120
+ url: string;
121
+ title?: string;
122
+ /** The heading path inside the page, such as `Pricing > Enterprise`. */
123
+ section?: string;
124
+ /** When the page last changed (ms). */
125
+ updatedAt?: number;
126
+ }
127
+ /** One chunk of text and its embedding. */
128
+ export interface VectorRecord {
129
+ id: string;
130
+ vector: Float32Array;
131
+ text: string;
132
+ source: VectorSource;
133
+ metadata?: Record<string, MetadataValue>;
134
+ }
135
+ /** A search result: the record without its vector, and how well it matched. */
136
+ export interface ScoredRecord {
137
+ id: string;
138
+ text: string;
139
+ source: VectorSource;
140
+ metadata?: Record<string, MetadataValue>;
141
+ /**
142
+ * Higher is better. `query` scores are cosine similarity (-1 to 1);
143
+ * `keywordQuery` scores depend on the store (BM25 in memory). The two
144
+ * aren't on the same scale, so hybrid search combines them by rank.
145
+ */
146
+ score: number;
147
+ }
148
+ export interface VectorQuery {
149
+ vector: Float32Array;
150
+ topK: number;
151
+ filter?: MetadataFilter;
152
+ }
153
+ export interface KeywordQuery {
154
+ text: string;
155
+ topK: number;
156
+ filter?: MetadataFilter;
157
+ }
158
+ /**
159
+ * Embedded chunks for retrieval. Every vector has `dimensions` numbers; a
160
+ * vector of another length is an error, both stored and searched.
161
+ */
162
+ export interface VectorStore {
163
+ readonly dimensions: number;
164
+ /** Adds records, replacing any with the same id. */
165
+ upsert(records: VectorRecord[]): Promise<void>;
166
+ /** The `topK` nearest records by cosine similarity, best first. */
167
+ query(query: VectorQuery): Promise<ScoredRecord[]>;
168
+ /** Full-text search, for hybrid retrieval. Best first. */
169
+ keywordQuery?(query: KeywordQuery): Promise<ScoredRecord[]>;
170
+ /** Removes every record from that source. */
171
+ deleteBySource(sourceId: string): Promise<void>;
172
+ }
173
+ /**
174
+ * Everything the server stores. Only `conversations` is required. Without
175
+ * `counters`, rate limits are kept per process; without `kv`, per-conversation
176
+ * locks are too.
177
+ */
178
+ export interface ChatCopsStorage {
179
+ conversations: ConversationStore;
180
+ counters?: CounterStore;
181
+ kv?: KeyValueStore;
182
+ events?: EventSink;
183
+ /** Embedded chunks, for answering from the site's own pages. */
184
+ vectors?: VectorStore;
185
+ /** Closes connections, for scripts and tests. */
186
+ close?(): Promise<void>;
187
+ }
188
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9C,uCAAuC;IACvC,IAAI,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,kFAAkF;IAClF,aAAa,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,sDAAsD;IACtD,aAAa,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,mCAAmC;IACnC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,oFAAoF;IACpF,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACzE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,uFAAuF;IACvF,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,KAAK,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CAClD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC,CAAC;AAE7E,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC1C;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,mEAAmE;IACnE,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACnD,0DAA0D;IAC1D,YAAY,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC5D,6CAA6C;IAC7C,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,gEAAgE;IAChE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,iDAAiD;IACjD,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import type { ChatCopsStorage } from '../storage/types.js';
2
+ export interface StorageConformanceOptions {
3
+ /**
4
+ * TTL used by the expiry checks, in ms. The checks wait about twice this.
5
+ * Default 150. Raise it for stores that round expiry to seconds.
6
+ */
7
+ ttlMs?: number;
8
+ /**
9
+ * Checks to leave out, for backends that can't meet them in a test run. For
10
+ * example Workers KV has a 60 second minimum TTL, so `'kv-ttl'`.
11
+ */
12
+ skip?: Array<'kv-ttl' | 'counter-ttl' | 'conversation-concurrency' | 'counter-concurrency' | 'vector-keyword-cjk'>;
13
+ }
14
+ /**
15
+ * The behavior every ChatCops store must have. Call it from a test file with a
16
+ * factory for your storage:
17
+ *
18
+ * ```ts
19
+ * import { runStorageConformance } from '@chatcops/core/testing';
20
+ * runStorageConformance('redis', () => redisStorage({ redis }));
21
+ * ```
22
+ *
23
+ * Optional capabilities (`counters`, `kv`, `events`, `vectors`, `list`,
24
+ * `purge`, `setIfAbsent`, `query`, `keywordQuery`) are checked only when the
25
+ * storage has them. The vector checks need at least 4 dimensions.
26
+ * `conversations.append`, `updateMessage` and `removeMessage` are required
27
+ * here: a store without them only gets the 0.4 behavior.
28
+ */
29
+ export declare function runStorageConformance(name: string, factory: () => ChatCopsStorage | Promise<ChatCopsStorage>, options?: StorageConformanceOptions): void;
30
+ //# sourceMappingURL=conformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../../src/testing/conformance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAA6B,MAAM,qBAAqB,CAAC;AAGtF,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,KAAK,CACV,QAAQ,GAAG,aAAa,GAAG,0BAA0B,GAAG,qBAAqB,GAAG,oBAAoB,CACrG,CAAC;CACH;AAsCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,EACzD,OAAO,GAAE,yBAA8B,GACtC,IAAI,CAyeN"}