@molroo-io/sdk 0.6.2 → 0.7.1

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 (252) hide show
  1. package/README.md +100 -194
  2. package/dist/cjs/api-client.d.ts +2 -12
  3. package/dist/cjs/api-client.d.ts.map +1 -1
  4. package/dist/cjs/api-client.js +4 -42
  5. package/dist/cjs/errors.d.ts +1 -16
  6. package/dist/cjs/errors.d.ts.map +1 -1
  7. package/dist/cjs/errors.js +2 -18
  8. package/dist/cjs/events/types.d.ts +14 -21
  9. package/dist/cjs/events/types.d.ts.map +1 -1
  10. package/dist/cjs/events/types.js +0 -11
  11. package/dist/cjs/index.d.ts +26 -48
  12. package/dist/cjs/index.d.ts.map +1 -1
  13. package/dist/cjs/index.js +29 -52
  14. package/dist/cjs/llm/resolve.d.ts +4 -22
  15. package/dist/cjs/llm/resolve.d.ts.map +1 -1
  16. package/dist/cjs/llm/resolve.js +19 -7
  17. package/dist/cjs/llm/vercel-ai/adapter.d.ts +4 -10
  18. package/dist/cjs/llm/vercel-ai/adapter.d.ts.map +1 -1
  19. package/dist/cjs/llm/vercel-ai/adapter.js +6 -152
  20. package/dist/cjs/llm/vercel-ai/config.d.ts +8 -5
  21. package/dist/cjs/llm/vercel-ai/config.d.ts.map +1 -1
  22. package/dist/cjs/memory/in-memory.d.ts +14 -37
  23. package/dist/cjs/memory/in-memory.d.ts.map +1 -1
  24. package/dist/cjs/memory/in-memory.js +22 -85
  25. package/dist/cjs/memory/recall.d.ts +10 -21
  26. package/dist/cjs/memory/recall.d.ts.map +1 -1
  27. package/dist/cjs/memory/recall.js +12 -91
  28. package/dist/cjs/memory/types.d.ts +46 -186
  29. package/dist/cjs/memory/types.d.ts.map +1 -1
  30. package/dist/cjs/memory/types.js +0 -10
  31. package/dist/cjs/persona/chat-orchestrator.d.ts +46 -0
  32. package/dist/cjs/persona/chat-orchestrator.d.ts.map +1 -0
  33. package/dist/cjs/persona/chat-orchestrator.js +240 -0
  34. package/dist/cjs/persona/event-emitter.d.ts +7 -0
  35. package/dist/cjs/persona/event-emitter.d.ts.map +1 -0
  36. package/dist/cjs/persona/event-emitter.js +53 -0
  37. package/dist/cjs/persona/memory-pipeline.d.ts +26 -0
  38. package/dist/cjs/persona/memory-pipeline.d.ts.map +1 -0
  39. package/dist/cjs/persona/memory-pipeline.js +69 -0
  40. package/dist/cjs/persona.d.ts +56 -187
  41. package/dist/cjs/persona.d.ts.map +1 -1
  42. package/dist/cjs/persona.js +62 -638
  43. package/dist/cjs/shared/appraisal.d.ts +26 -0
  44. package/dist/cjs/shared/appraisal.d.ts.map +1 -0
  45. package/dist/cjs/shared/appraisal.js +45 -0
  46. package/dist/cjs/shared/client-factory.d.ts +23 -0
  47. package/dist/cjs/shared/client-factory.d.ts.map +1 -0
  48. package/dist/cjs/shared/client-factory.js +48 -0
  49. package/dist/cjs/shared/errors.d.ts +21 -0
  50. package/dist/cjs/shared/errors.d.ts.map +1 -0
  51. package/dist/cjs/shared/errors.js +29 -0
  52. package/dist/cjs/world/client.d.ts +2 -9
  53. package/dist/cjs/world/client.d.ts.map +1 -1
  54. package/dist/cjs/world/client.js +7 -34
  55. package/dist/cjs/world/errors.d.ts +1 -8
  56. package/dist/cjs/world/errors.d.ts.map +1 -1
  57. package/dist/cjs/world/errors.js +2 -12
  58. package/dist/cjs/world/index.d.ts +2 -2
  59. package/dist/cjs/world/index.d.ts.map +1 -1
  60. package/dist/cjs/world/types.d.ts +32 -5
  61. package/dist/cjs/world/types.d.ts.map +1 -1
  62. package/dist/cjs/world/world-domain.d.ts.map +1 -1
  63. package/dist/cjs/world/world-domain.js +4 -32
  64. package/dist/cjs/world/world-persona.d.ts +17 -12
  65. package/dist/cjs/world/world-persona.d.ts.map +1 -1
  66. package/dist/cjs/world/world-persona.js +6 -18
  67. package/dist/cjs/world/world.d.ts +28 -5
  68. package/dist/cjs/world/world.d.ts.map +1 -1
  69. package/dist/cjs/world/world.js +13 -11
  70. package/dist/esm/api-client.d.ts +2 -12
  71. package/dist/esm/api-client.d.ts.map +1 -1
  72. package/dist/esm/api-client.js +3 -38
  73. package/dist/esm/errors.d.ts +1 -16
  74. package/dist/esm/errors.d.ts.map +1 -1
  75. package/dist/esm/errors.js +1 -17
  76. package/dist/esm/events/types.d.ts +14 -21
  77. package/dist/esm/events/types.d.ts.map +1 -1
  78. package/dist/esm/events/types.js +0 -11
  79. package/dist/esm/index.d.ts +26 -48
  80. package/dist/esm/index.d.ts.map +1 -1
  81. package/dist/esm/index.js +25 -38
  82. package/dist/esm/llm/resolve.d.ts +4 -22
  83. package/dist/esm/llm/resolve.d.ts.map +1 -1
  84. package/dist/esm/llm/resolve.js +20 -8
  85. package/dist/esm/llm/vercel-ai/adapter.d.ts +4 -10
  86. package/dist/esm/llm/vercel-ai/adapter.d.ts.map +1 -1
  87. package/dist/esm/llm/vercel-ai/adapter.js +6 -119
  88. package/dist/esm/llm/vercel-ai/config.d.ts +8 -5
  89. package/dist/esm/llm/vercel-ai/config.d.ts.map +1 -1
  90. package/dist/esm/memory/in-memory.d.ts +14 -37
  91. package/dist/esm/memory/in-memory.d.ts.map +1 -1
  92. package/dist/esm/memory/in-memory.js +20 -83
  93. package/dist/esm/memory/recall.d.ts +10 -21
  94. package/dist/esm/memory/recall.d.ts.map +1 -1
  95. package/dist/esm/memory/recall.js +12 -91
  96. package/dist/esm/memory/types.d.ts +46 -186
  97. package/dist/esm/memory/types.d.ts.map +1 -1
  98. package/dist/esm/memory/types.js +1 -9
  99. package/dist/esm/persona/chat-orchestrator.d.ts +46 -0
  100. package/dist/esm/persona/chat-orchestrator.d.ts.map +1 -0
  101. package/dist/esm/persona/chat-orchestrator.js +204 -0
  102. package/dist/esm/persona/event-emitter.d.ts +7 -0
  103. package/dist/esm/persona/event-emitter.d.ts.map +1 -0
  104. package/dist/esm/persona/event-emitter.js +50 -0
  105. package/dist/esm/persona/memory-pipeline.d.ts +26 -0
  106. package/dist/esm/persona/memory-pipeline.d.ts.map +1 -0
  107. package/dist/esm/persona/memory-pipeline.js +65 -0
  108. package/dist/esm/persona.d.ts +56 -187
  109. package/dist/esm/persona.d.ts.map +1 -1
  110. package/dist/esm/persona.js +62 -638
  111. package/dist/esm/shared/appraisal.d.ts +26 -0
  112. package/dist/esm/shared/appraisal.d.ts.map +1 -0
  113. package/dist/esm/shared/appraisal.js +40 -0
  114. package/dist/esm/shared/client-factory.d.ts +23 -0
  115. package/dist/esm/shared/client-factory.d.ts.map +1 -0
  116. package/dist/esm/shared/client-factory.js +41 -0
  117. package/dist/esm/shared/errors.d.ts +21 -0
  118. package/dist/esm/shared/errors.d.ts.map +1 -0
  119. package/dist/esm/shared/errors.js +24 -0
  120. package/dist/esm/world/client.d.ts +2 -9
  121. package/dist/esm/world/client.d.ts.map +1 -1
  122. package/dist/esm/world/client.js +6 -30
  123. package/dist/esm/world/errors.d.ts +1 -8
  124. package/dist/esm/world/errors.d.ts.map +1 -1
  125. package/dist/esm/world/errors.js +1 -11
  126. package/dist/esm/world/index.d.ts +2 -2
  127. package/dist/esm/world/index.d.ts.map +1 -1
  128. package/dist/esm/world/types.d.ts +32 -5
  129. package/dist/esm/world/types.d.ts.map +1 -1
  130. package/dist/esm/world/world-domain.d.ts.map +1 -1
  131. package/dist/esm/world/world-domain.js +4 -32
  132. package/dist/esm/world/world-persona.d.ts +17 -12
  133. package/dist/esm/world/world-persona.d.ts.map +1 -1
  134. package/dist/esm/world/world-persona.js +6 -18
  135. package/dist/esm/world/world.d.ts +28 -5
  136. package/dist/esm/world/world.d.ts.map +1 -1
  137. package/dist/esm/world/world.js +13 -11
  138. package/package.json +4 -101
  139. package/dist/cjs/embedding/cloudflare.d.ts +0 -15
  140. package/dist/cjs/embedding/cloudflare.d.ts.map +0 -1
  141. package/dist/cjs/embedding/cloudflare.js +0 -16
  142. package/dist/cjs/embedding/cohere.d.ts +0 -8
  143. package/dist/cjs/embedding/cohere.d.ts.map +0 -1
  144. package/dist/cjs/embedding/cohere.js +0 -31
  145. package/dist/cjs/embedding/index.d.ts +0 -9
  146. package/dist/cjs/embedding/index.d.ts.map +0 -1
  147. package/dist/cjs/embedding/index.js +0 -11
  148. package/dist/cjs/embedding/local.d.ts +0 -6
  149. package/dist/cjs/embedding/local.d.ts.map +0 -1
  150. package/dist/cjs/embedding/local.js +0 -28
  151. package/dist/cjs/embedding/openai.d.ts +0 -9
  152. package/dist/cjs/embedding/openai.d.ts.map +0 -1
  153. package/dist/cjs/embedding/openai.js +0 -26
  154. package/dist/cjs/events/console.d.ts +0 -25
  155. package/dist/cjs/events/console.d.ts.map +0 -1
  156. package/dist/cjs/events/console.js +0 -41
  157. package/dist/cjs/events/webhook.d.ts +0 -30
  158. package/dist/cjs/events/webhook.d.ts.map +0 -1
  159. package/dist/cjs/events/webhook.js +0 -79
  160. package/dist/cjs/memory/cloudflare/index.d.ts +0 -3
  161. package/dist/cjs/memory/cloudflare/index.d.ts.map +0 -1
  162. package/dist/cjs/memory/cloudflare/index.js +0 -5
  163. package/dist/cjs/memory/cloudflare/vectorize.d.ts +0 -62
  164. package/dist/cjs/memory/cloudflare/vectorize.d.ts.map +0 -1
  165. package/dist/cjs/memory/cloudflare/vectorize.js +0 -55
  166. package/dist/cjs/memory/in-memory-semantic.d.ts +0 -16
  167. package/dist/cjs/memory/in-memory-semantic.d.ts.map +0 -1
  168. package/dist/cjs/memory/in-memory-semantic.js +0 -57
  169. package/dist/cjs/memory/pinecone/index.d.ts +0 -7
  170. package/dist/cjs/memory/pinecone/index.d.ts.map +0 -1
  171. package/dist/cjs/memory/pinecone/index.js +0 -8
  172. package/dist/cjs/memory/pinecone/memory-adapter.d.ts +0 -62
  173. package/dist/cjs/memory/pinecone/memory-adapter.d.ts.map +0 -1
  174. package/dist/cjs/memory/pinecone/memory-adapter.js +0 -220
  175. package/dist/cjs/memory/pinecone/semantic.d.ts +0 -44
  176. package/dist/cjs/memory/pinecone/semantic.d.ts.map +0 -1
  177. package/dist/cjs/memory/pinecone/semantic.js +0 -90
  178. package/dist/cjs/memory/sqlite/index.d.ts +0 -3
  179. package/dist/cjs/memory/sqlite/index.d.ts.map +0 -1
  180. package/dist/cjs/memory/sqlite/index.js +0 -5
  181. package/dist/cjs/memory/sqlite/memory-adapter.d.ts +0 -58
  182. package/dist/cjs/memory/sqlite/memory-adapter.d.ts.map +0 -1
  183. package/dist/cjs/memory/sqlite/memory-adapter.js +0 -336
  184. package/dist/cjs/memory/sqlite/schema.d.ts +0 -4
  185. package/dist/cjs/memory/sqlite/schema.d.ts.map +0 -1
  186. package/dist/cjs/memory/sqlite/schema.js +0 -91
  187. package/dist/cjs/memory/supabase/index.d.ts +0 -7
  188. package/dist/cjs/memory/supabase/index.d.ts.map +0 -1
  189. package/dist/cjs/memory/supabase/index.js +0 -8
  190. package/dist/cjs/memory/supabase/memory-adapter.d.ts +0 -67
  191. package/dist/cjs/memory/supabase/memory-adapter.d.ts.map +0 -1
  192. package/dist/cjs/memory/supabase/memory-adapter.js +0 -335
  193. package/dist/cjs/memory/supabase/semantic.d.ts +0 -44
  194. package/dist/cjs/memory/supabase/semantic.d.ts.map +0 -1
  195. package/dist/cjs/memory/supabase/semantic.js +0 -72
  196. package/dist/esm/embedding/cloudflare.d.ts +0 -15
  197. package/dist/esm/embedding/cloudflare.d.ts.map +0 -1
  198. package/dist/esm/embedding/cloudflare.js +0 -13
  199. package/dist/esm/embedding/cohere.d.ts +0 -8
  200. package/dist/esm/embedding/cohere.d.ts.map +0 -1
  201. package/dist/esm/embedding/cohere.js +0 -28
  202. package/dist/esm/embedding/index.d.ts +0 -9
  203. package/dist/esm/embedding/index.d.ts.map +0 -1
  204. package/dist/esm/embedding/index.js +0 -4
  205. package/dist/esm/embedding/local.d.ts +0 -6
  206. package/dist/esm/embedding/local.d.ts.map +0 -1
  207. package/dist/esm/embedding/local.js +0 -25
  208. package/dist/esm/embedding/openai.d.ts +0 -9
  209. package/dist/esm/embedding/openai.d.ts.map +0 -1
  210. package/dist/esm/embedding/openai.js +0 -23
  211. package/dist/esm/events/console.d.ts +0 -25
  212. package/dist/esm/events/console.d.ts.map +0 -1
  213. package/dist/esm/events/console.js +0 -37
  214. package/dist/esm/events/webhook.d.ts +0 -30
  215. package/dist/esm/events/webhook.d.ts.map +0 -1
  216. package/dist/esm/events/webhook.js +0 -75
  217. package/dist/esm/memory/cloudflare/index.d.ts +0 -3
  218. package/dist/esm/memory/cloudflare/index.d.ts.map +0 -1
  219. package/dist/esm/memory/cloudflare/index.js +0 -1
  220. package/dist/esm/memory/cloudflare/vectorize.d.ts +0 -62
  221. package/dist/esm/memory/cloudflare/vectorize.d.ts.map +0 -1
  222. package/dist/esm/memory/cloudflare/vectorize.js +0 -51
  223. package/dist/esm/memory/in-memory-semantic.d.ts +0 -16
  224. package/dist/esm/memory/in-memory-semantic.d.ts.map +0 -1
  225. package/dist/esm/memory/in-memory-semantic.js +0 -53
  226. package/dist/esm/memory/pinecone/index.d.ts +0 -7
  227. package/dist/esm/memory/pinecone/index.d.ts.map +0 -1
  228. package/dist/esm/memory/pinecone/index.js +0 -3
  229. package/dist/esm/memory/pinecone/memory-adapter.d.ts +0 -62
  230. package/dist/esm/memory/pinecone/memory-adapter.d.ts.map +0 -1
  231. package/dist/esm/memory/pinecone/memory-adapter.js +0 -216
  232. package/dist/esm/memory/pinecone/semantic.d.ts +0 -44
  233. package/dist/esm/memory/pinecone/semantic.d.ts.map +0 -1
  234. package/dist/esm/memory/pinecone/semantic.js +0 -86
  235. package/dist/esm/memory/sqlite/index.d.ts +0 -3
  236. package/dist/esm/memory/sqlite/index.d.ts.map +0 -1
  237. package/dist/esm/memory/sqlite/index.js +0 -1
  238. package/dist/esm/memory/sqlite/memory-adapter.d.ts +0 -58
  239. package/dist/esm/memory/sqlite/memory-adapter.d.ts.map +0 -1
  240. package/dist/esm/memory/sqlite/memory-adapter.js +0 -296
  241. package/dist/esm/memory/sqlite/schema.d.ts +0 -4
  242. package/dist/esm/memory/sqlite/schema.d.ts.map +0 -1
  243. package/dist/esm/memory/sqlite/schema.js +0 -86
  244. package/dist/esm/memory/supabase/index.d.ts +0 -7
  245. package/dist/esm/memory/supabase/index.d.ts.map +0 -1
  246. package/dist/esm/memory/supabase/index.js +0 -3
  247. package/dist/esm/memory/supabase/memory-adapter.d.ts +0 -67
  248. package/dist/esm/memory/supabase/memory-adapter.d.ts.map +0 -1
  249. package/dist/esm/memory/supabase/memory-adapter.js +0 -331
  250. package/dist/esm/memory/supabase/semantic.d.ts +0 -44
  251. package/dist/esm/memory/supabase/semantic.d.ts.map +0 -1
  252. package/dist/esm/memory/supabase/semantic.js +0 -68
@@ -1,37 +0,0 @@
1
- /**
2
- * Console-based EventAdapter for development/debugging.
3
- * Logs events to console (or a custom logger function).
4
- */
5
- export class ConsoleEventAdapter {
6
- constructor(options) {
7
- this.prefix = options?.prefix ?? '[molroo]';
8
- this.filter = new Set(options?.filter ?? []);
9
- this.format = options?.format ?? 'human';
10
- this.logger = options?.logger ?? console.log;
11
- }
12
- async emit(event) {
13
- if (this.filter.size > 0 && !this.filter.has(event.type)) {
14
- return;
15
- }
16
- if (this.format === 'json') {
17
- this.logger(`${this.prefix} ${JSON.stringify(event)}`);
18
- }
19
- else {
20
- const time = new Date(event.timestamp).toISOString();
21
- this.logger(`${this.prefix} ${time} ${event.type}: ${summarize(event.payload)}`);
22
- }
23
- }
24
- async emitBatch(events) {
25
- for (const event of events) {
26
- await this.emit(event);
27
- }
28
- }
29
- }
30
- function summarize(payload) {
31
- const keys = Object.keys(payload);
32
- if (keys.length === 0)
33
- return '{}';
34
- if (keys.length <= 3)
35
- return JSON.stringify(payload);
36
- return `{${keys.slice(0, 3).join(', ')} + ${keys.length - 3} more}`;
37
- }
@@ -1,30 +0,0 @@
1
- import type { EventAdapter, SDKEvent } from './types';
2
- export interface WebhookEventAdapterOptions {
3
- /** Webhook endpoint URL. */
4
- url: string;
5
- /** HMAC secret for signing payloads. Optional. */
6
- secret?: string;
7
- /** Max retry attempts on server errors. Default: 2. */
8
- maxRetries?: number;
9
- /** Request timeout in ms. Default: 5000. */
10
- timeoutMs?: number;
11
- /** Additional HTTP headers. */
12
- headers?: Record<string, string>;
13
- }
14
- /**
15
- * Webhook-based EventAdapter for production event delivery.
16
- * Sends events as POST requests with optional HMAC signing and retry.
17
- */
18
- export declare class WebhookEventAdapter implements EventAdapter {
19
- private url;
20
- private secret?;
21
- private maxRetries;
22
- private timeoutMs;
23
- private headers;
24
- constructor(options: WebhookEventAdapterOptions);
25
- emit(event: SDKEvent): Promise<void>;
26
- emitBatch(events: SDKEvent[]): Promise<void>;
27
- private post;
28
- private sign;
29
- }
30
- //# sourceMappingURL=webhook.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/events/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGtD,MAAM,WAAW,0BAA0B;IACzC,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,EAAE,0BAA0B;IAQzC,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAIpC,IAAI;IAwDlB,OAAO,CAAC,IAAI;CAIb"}
@@ -1,75 +0,0 @@
1
- import { createHmac } from 'node:crypto';
2
- /**
3
- * Webhook-based EventAdapter for production event delivery.
4
- * Sends events as POST requests with optional HMAC signing and retry.
5
- */
6
- export class WebhookEventAdapter {
7
- constructor(options) {
8
- this.url = options.url;
9
- this.secret = options.secret;
10
- this.maxRetries = options.maxRetries ?? 2;
11
- this.timeoutMs = options.timeoutMs ?? 5000;
12
- this.headers = options.headers ?? {};
13
- }
14
- async emit(event) {
15
- await this.post(event);
16
- }
17
- async emitBatch(events) {
18
- await this.post(events);
19
- }
20
- async post(body) {
21
- const jsonBody = JSON.stringify(body);
22
- const timestamp = Math.floor(Date.now() / 1000);
23
- const headers = {
24
- 'Content-Type': 'application/json',
25
- ...this.headers,
26
- };
27
- if (this.secret) {
28
- const signature = this.sign(timestamp, jsonBody);
29
- headers['X-Molroo-Signature'] = `t=${timestamp},v1=${signature}`;
30
- }
31
- let lastError;
32
- for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
33
- if (attempt > 0) {
34
- await sleep(200 * Math.pow(2, attempt - 1));
35
- }
36
- const controller = new AbortController();
37
- const timer = setTimeout(() => controller.abort(), this.timeoutMs);
38
- try {
39
- const response = await fetch(this.url, {
40
- method: 'POST',
41
- headers,
42
- body: jsonBody,
43
- signal: controller.signal,
44
- });
45
- clearTimeout(timer);
46
- if (response.ok)
47
- return;
48
- if (response.status >= 400 && response.status < 500) {
49
- throw new Error(`Webhook rejected: ${response.status} ${response.statusText}`);
50
- }
51
- lastError = new Error(`Webhook failed: ${response.status} ${response.statusText}`);
52
- }
53
- catch (err) {
54
- clearTimeout(timer);
55
- if (err.name === 'AbortError') {
56
- lastError = new Error(`Webhook timeout after ${this.timeoutMs}ms`);
57
- }
58
- else if (err.message?.startsWith('Webhook rejected')) {
59
- throw err;
60
- }
61
- else {
62
- lastError = err;
63
- }
64
- }
65
- }
66
- throw lastError ?? new Error('Webhook delivery failed');
67
- }
68
- sign(timestamp, body) {
69
- const payload = `${timestamp}.${body}`;
70
- return createHmac('sha256', this.secret).update(payload).digest('hex');
71
- }
72
- }
73
- function sleep(ms) {
74
- return new Promise((resolve) => setTimeout(resolve, ms));
75
- }
@@ -1,3 +0,0 @@
1
- export { CloudflareVectorizeMemory } from './vectorize';
2
- export type { CloudflareVectorizeMemoryOptions, VectorizeIndex } from './vectorize';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/cloudflare/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +0,0 @@
1
- export { CloudflareVectorizeMemory } from './vectorize';
@@ -1,62 +0,0 @@
1
- import type { EmbeddingAdapter } from '../types';
2
- import type { SemanticMemory, SearchOptions, SearchResult } from '../semantic';
3
- /**
4
- * Minimal Cloudflare Vectorize binding types.
5
- * Avoids requiring @cloudflare/workers-types at compile time.
6
- */
7
- export interface VectorizeIndex {
8
- upsert(vectors: VectorizeVector[]): Promise<{
9
- count: number;
10
- }>;
11
- query(vector: number[], options: {
12
- topK: number;
13
- returnMetadata?: 'all' | 'indexed' | 'none';
14
- filter?: Record<string, unknown>;
15
- }): Promise<{
16
- matches: VectorizeMatch[];
17
- }>;
18
- deleteByIds(ids: string[]): Promise<{
19
- count: number;
20
- }>;
21
- }
22
- export interface VectorizeVector {
23
- id: string;
24
- values: number[];
25
- metadata?: Record<string, unknown>;
26
- }
27
- export interface VectorizeMatch {
28
- id: string;
29
- score: number;
30
- metadata?: Record<string, unknown>;
31
- }
32
- export interface CloudflareVectorizeMemoryOptions {
33
- /** Cloudflare Vectorize index binding. */
34
- index: VectorizeIndex;
35
- /** Embedding provider (embed function + dimension). */
36
- embedding: EmbeddingAdapter;
37
- }
38
- /**
39
- * Cloudflare Vectorize-backed SemanticMemory.
40
- *
41
- * Stores original text in Vectorize metadata (10KB limit per vector,
42
- * more than enough for chat messages).
43
- *
44
- * @example
45
- * ```typescript
46
- * const memory = new CloudflareVectorizeMemory({
47
- * index: env.VECTORIZE_INDEX,
48
- * embedding: cloudflareAIEmbedding({ ai: env.AI }),
49
- * });
50
- * await memory.store('The user likes coffee', { userId: '123' });
51
- * const results = await memory.search('beverage preferences');
52
- * ```
53
- */
54
- export declare class CloudflareVectorizeMemory implements SemanticMemory {
55
- private index;
56
- private embedding;
57
- constructor(options: CloudflareVectorizeMemoryOptions);
58
- store(text: string, metadata?: Record<string, unknown>): Promise<string>;
59
- search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
60
- delete(ids: string[]): Promise<void>;
61
- }
62
- //# sourceMappingURL=vectorize.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vectorize.d.ts","sourceRoot":"","sources":["../../../../src/memory/cloudflare/vectorize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/E;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,CACH,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;QAC5C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,GACA,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IAC1C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gCAAgC;IAC/C,0CAA0C;IAC1C,KAAK,EAAE,cAAc,CAAC;IACtB,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAC9D,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,SAAS,CAAmB;gBAExB,OAAO,EAAE,gCAAgC;IAK/C,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,CAAC;IAOZ,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IAqBpB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAK3C"}
@@ -1,51 +0,0 @@
1
- /**
2
- * Cloudflare Vectorize-backed SemanticMemory.
3
- *
4
- * Stores original text in Vectorize metadata (10KB limit per vector,
5
- * more than enough for chat messages).
6
- *
7
- * @example
8
- * ```typescript
9
- * const memory = new CloudflareVectorizeMemory({
10
- * index: env.VECTORIZE_INDEX,
11
- * embedding: cloudflareAIEmbedding({ ai: env.AI }),
12
- * });
13
- * await memory.store('The user likes coffee', { userId: '123' });
14
- * const results = await memory.search('beverage preferences');
15
- * ```
16
- */
17
- export class CloudflareVectorizeMemory {
18
- constructor(options) {
19
- this.index = options.index;
20
- this.embedding = options.embedding;
21
- }
22
- async store(text, metadata = {}) {
23
- const id = crypto.randomUUID();
24
- const values = await this.embedding.embed(text);
25
- await this.index.upsert([{ id, values, metadata: { text, ...metadata } }]);
26
- return id;
27
- }
28
- async search(query, options = {}) {
29
- const topK = options.topK ?? 5;
30
- const threshold = options.scoreThreshold ?? 0;
31
- const vector = await this.embedding.embed(query);
32
- const { matches } = await this.index.query(vector, {
33
- topK,
34
- returnMetadata: 'all',
35
- filter: options.filter,
36
- });
37
- return matches
38
- .filter((m) => m.score >= threshold)
39
- .map((m) => ({
40
- id: m.id,
41
- text: m.metadata?.text ?? '',
42
- score: m.score,
43
- metadata: m.metadata ?? {},
44
- }));
45
- }
46
- async delete(ids) {
47
- if (ids.length > 0) {
48
- await this.index.deleteByIds(ids);
49
- }
50
- }
51
- }
@@ -1,16 +0,0 @@
1
- import type { EmbeddingAdapter } from './types';
2
- import type { SemanticMemory, SearchOptions, SearchResult } from './semantic';
3
- /**
4
- * In-memory SemanticMemory for local development and testing.
5
- * Stores embeddings in a Map and performs brute-force cosine similarity search.
6
- */
7
- export declare class InMemorySemanticMemory implements SemanticMemory {
8
- private embedding;
9
- private entries;
10
- private counter;
11
- constructor(embedding: EmbeddingAdapter);
12
- store(text: string, metadata?: Record<string, unknown>): Promise<string>;
13
- search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
14
- delete(ids: string[]): Promise<void>;
15
- }
16
- //# sourceMappingURL=in-memory-semantic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"in-memory-semantic.d.ts","sourceRoot":"","sources":["../../../src/memory/in-memory-semantic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAsB9E;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAI/C,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAAK;gBAEA,SAAS,EAAE,gBAAgB;IAEzC,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,CAAC;IAOZ,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IAsBpB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAK3C"}
@@ -1,53 +0,0 @@
1
- function cosineSimilarity(a, b) {
2
- let dot = 0;
3
- let normA = 0;
4
- let normB = 0;
5
- for (let i = 0; i < a.length; i++) {
6
- dot += a[i] * b[i];
7
- normA += a[i] * a[i];
8
- normB += b[i] * b[i];
9
- }
10
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
11
- return denom === 0 ? 0 : dot / denom;
12
- }
13
- /**
14
- * In-memory SemanticMemory for local development and testing.
15
- * Stores embeddings in a Map and performs brute-force cosine similarity search.
16
- */
17
- export class InMemorySemanticMemory {
18
- constructor(embedding) {
19
- this.embedding = embedding;
20
- this.entries = new Map();
21
- this.counter = 0;
22
- }
23
- async store(text, metadata = {}) {
24
- const id = `mem_${++this.counter}`;
25
- const vector = await this.embedding.embed(text);
26
- this.entries.set(id, { id, text, embedding: vector, metadata });
27
- return id;
28
- }
29
- async search(query, options = {}) {
30
- const topK = options.topK ?? 5;
31
- const threshold = options.scoreThreshold ?? 0;
32
- const queryVec = await this.embedding.embed(query);
33
- const scored = [];
34
- for (const entry of this.entries.values()) {
35
- const score = cosineSimilarity(queryVec, entry.embedding);
36
- if (score >= threshold) {
37
- scored.push({
38
- id: entry.id,
39
- text: entry.text,
40
- score,
41
- metadata: entry.metadata,
42
- });
43
- }
44
- }
45
- scored.sort((a, b) => b.score - a.score);
46
- return scored.slice(0, topK);
47
- }
48
- async delete(ids) {
49
- for (const id of ids) {
50
- this.entries.delete(id);
51
- }
52
- }
53
- }
@@ -1,7 +0,0 @@
1
- export { PineconeSemanticMemory } from './semantic';
2
- export type { PineconeSemanticMemoryOptions } from './semantic';
3
- /** @deprecated Use PineconeSemanticMemory */
4
- export { PineconeMemoryAdapter } from './memory-adapter';
5
- /** @deprecated Use PineconeSemanticMemoryOptions */
6
- export type { PineconeMemoryAdapterOptions } from './memory-adapter';
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/pinecone/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,6CAA6C;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,oDAAoD;AACpD,YAAY,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,3 +0,0 @@
1
- export { PineconeSemanticMemory } from './semantic';
2
- /** @deprecated Use PineconeSemanticMemory */
3
- export { PineconeMemoryAdapter } from './memory-adapter';
@@ -1,62 +0,0 @@
1
- import type { MemoryAdapter, Episode, Reflection, RecallQuery, SemanticRecallOptions, EpisodePatch, CountQuery, EmbeddingAdapter } from '../types';
2
- export interface PineconeMemoryAdapterOptions {
3
- /** Pinecone API key. */
4
- apiKey: string;
5
- /** Pinecone index name. */
6
- indexName: string;
7
- /** Pinecone namespace. Default: 'default'. */
8
- namespace?: string;
9
- /** Embedding provider (embed function + dimension). */
10
- embedding: EmbeddingAdapter;
11
- }
12
- /**
13
- * Pinecone-backed MemoryAdapter combining in-memory arrays (RDB) with
14
- * Pinecone vector search (semanticRecall).
15
- *
16
- * RDB operations (saveEpisode, recall, saveReflection, getReflections,
17
- * getByIds, countEpisodes, updateEpisode, deleteEpisode, expireEpisodes)
18
- * all operate on in-memory arrays, identical to InMemoryAdapter.
19
- *
20
- * Vector search (semanticRecall) delegates to Pinecone after embedding
21
- * the query text via the provided EmbeddingAdapter.
22
- *
23
- * @example
24
- * ```typescript
25
- * const memory = new PineconeMemoryAdapter({
26
- * apiKey: process.env.PINECONE_API_KEY!,
27
- * indexName: 'molroo-memory',
28
- * namespace: 'world-123',
29
- * embedding: openaiEmbedding({ apiKey: '...' }),
30
- * });
31
- * await memory.init();
32
- * ```
33
- */
34
- export declare class PineconeMemoryAdapter implements MemoryAdapter {
35
- private client;
36
- private pcIndex;
37
- private namespace;
38
- private indexName;
39
- private embedding;
40
- private initialized;
41
- private episodes;
42
- private reflections;
43
- constructor(options: PineconeMemoryAdapterOptions);
44
- /**
45
- * Initialize the adapter. Must be called before use.
46
- * Validates embedding dimension against Pinecone index.
47
- */
48
- init(): Promise<void>;
49
- private ensureInitialized;
50
- private ns;
51
- saveEpisode(episode: Episode): Promise<void>;
52
- recall(query: RecallQuery): Promise<Episode[]>;
53
- saveReflection(reflection: Reflection): Promise<void>;
54
- getReflections(sourceEntity?: string): Promise<Reflection[]>;
55
- semanticRecall(query: string, options?: SemanticRecallOptions): Promise<Episode[]>;
56
- getByIds(ids: string[]): Promise<Episode[]>;
57
- countEpisodes(query: CountQuery): Promise<number>;
58
- updateEpisode(id: string, patch: EpisodePatch): Promise<void>;
59
- deleteEpisode(id: string): Promise<void>;
60
- expireEpisodes(before: number, minImportance?: number): Promise<number>;
61
- }
62
- //# sourceMappingURL=memory-adapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory-adapter.d.ts","sourceRoot":"","sources":["../../../../src/memory/pinecone/memory-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,OAAO,EACP,UAAU,EACV,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,4BAA4B;IAC3C,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAoB;gBAE3B,OAAO,EAAE,4BAA4B;IAOjD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,EAAE;IAMJ,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB5C,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuC9C,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAU5D,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,OAAO,EAAE,CAAC;IAqCf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAM3C,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBjD,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxC,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;CA2BnB"}
@@ -1,216 +0,0 @@
1
- import { Pinecone } from '@pinecone-database/pinecone';
2
- /**
3
- * Pinecone-backed MemoryAdapter combining in-memory arrays (RDB) with
4
- * Pinecone vector search (semanticRecall).
5
- *
6
- * RDB operations (saveEpisode, recall, saveReflection, getReflections,
7
- * getByIds, countEpisodes, updateEpisode, deleteEpisode, expireEpisodes)
8
- * all operate on in-memory arrays, identical to InMemoryAdapter.
9
- *
10
- * Vector search (semanticRecall) delegates to Pinecone after embedding
11
- * the query text via the provided EmbeddingAdapter.
12
- *
13
- * @example
14
- * ```typescript
15
- * const memory = new PineconeMemoryAdapter({
16
- * apiKey: process.env.PINECONE_API_KEY!,
17
- * indexName: 'molroo-memory',
18
- * namespace: 'world-123',
19
- * embedding: openaiEmbedding({ apiKey: '...' }),
20
- * });
21
- * await memory.init();
22
- * ```
23
- */
24
- export class PineconeMemoryAdapter {
25
- constructor(options) {
26
- this.initialized = false;
27
- this.episodes = [];
28
- this.reflections = [];
29
- this.client = new Pinecone({ apiKey: options.apiKey });
30
- this.indexName = options.indexName;
31
- this.namespace = options.namespace ?? 'default';
32
- this.embedding = options.embedding;
33
- }
34
- /**
35
- * Initialize the adapter. Must be called before use.
36
- * Validates embedding dimension against Pinecone index.
37
- */
38
- async init() {
39
- this.pcIndex = this.client.index(this.indexName);
40
- const stats = await this.pcIndex.describeIndexStats();
41
- if (stats.dimension && stats.dimension !== this.embedding.dimension) {
42
- throw new Error(`Dimension mismatch: Pinecone index expects ${stats.dimension}d, ` +
43
- `but embedding provider has ${this.embedding.dimension}d`);
44
- }
45
- this.initialized = true;
46
- }
47
- ensureInitialized() {
48
- if (!this.initialized) {
49
- throw new Error('PineconeMemoryAdapter not initialized. Call init() first.');
50
- }
51
- }
52
- ns() {
53
- return this.pcIndex.namespace(this.namespace);
54
- }
55
- // ── Required methods (in-memory, identical to InMemoryAdapter) ──
56
- async saveEpisode(episode) {
57
- this.ensureInitialized();
58
- this.episodes.push(episode);
59
- // Auto-upsert embedding to Pinecone (best-effort)
60
- const text = episode.context ?? episode.sourceEntity ?? '';
61
- if (text) {
62
- try {
63
- const embedding = await this.embedding.embed(text);
64
- await this.ns().upsert([{
65
- id: episode.id,
66
- values: embedding,
67
- metadata: {
68
- type: 'episode',
69
- sourceEntity: episode.sourceEntity ?? '',
70
- timestamp: episode.timestamp,
71
- importance: episode.importance,
72
- },
73
- }]);
74
- }
75
- catch {
76
- // Best-effort: vector indexing failure doesn't block episode save.
77
- }
78
- }
79
- }
80
- async recall(query) {
81
- this.ensureInitialized();
82
- let results = this.episodes;
83
- if (query.sourceEntity) {
84
- results = results.filter((e) => e.sourceEntity === query.sourceEntity);
85
- }
86
- if (query.context) {
87
- const ctx = query.context.toLowerCase();
88
- results = results.filter((e) => e.context && e.context.toLowerCase().includes(ctx));
89
- }
90
- if (query.valenceRange) {
91
- const [min, max] = query.valenceRange;
92
- results = results.filter((e) => e.emotionSnapshot.V >= min && e.emotionSnapshot.V <= max);
93
- }
94
- if (query.minImportance !== undefined) {
95
- results = results.filter((e) => e.importance >= query.minImportance);
96
- }
97
- if (query.timeRange) {
98
- const [start, end] = query.timeRange;
99
- results = results.filter((e) => e.timestamp >= start && e.timestamp <= end);
100
- }
101
- // Return most recent first
102
- results = results.slice().sort((a, b) => b.timestamp - a.timestamp);
103
- if (query.limit && query.limit > 0) {
104
- results = results.slice(0, query.limit);
105
- }
106
- return results;
107
- }
108
- async saveReflection(reflection) {
109
- this.ensureInitialized();
110
- this.reflections.push(reflection);
111
- }
112
- async getReflections(sourceEntity) {
113
- this.ensureInitialized();
114
- if (sourceEntity) {
115
- return this.reflections.filter((r) => r.sourceEntity === sourceEntity);
116
- }
117
- return [...this.reflections];
118
- }
119
- // ── Optional methods ──
120
- async semanticRecall(query, options) {
121
- this.ensureInitialized();
122
- const embedding = await this.embedding.embed(query);
123
- const topK = options?.topK ?? 5;
124
- // Build Pinecone filter
125
- const filter = {};
126
- if (options?.filter?.sourceEntity) {
127
- filter.sourceEntity = { $eq: options.filter.sourceEntity };
128
- }
129
- if (options?.filter?.minImportance !== undefined) {
130
- filter.importance = { $gte: options.filter.minImportance };
131
- }
132
- // Over-fetch to account for in-memory-only episodes that may not be in Pinecone
133
- const hasFilter = Object.keys(filter).length > 0;
134
- const fetchK = hasFilter ? topK * 4 : topK;
135
- const results = await this.ns().query({
136
- vector: embedding,
137
- topK: fetchK,
138
- filter: hasFilter ? filter : undefined,
139
- includeMetadata: true,
140
- });
141
- // Map Pinecone results to episodes via in-memory lookup
142
- const matches = results.matches ?? [];
143
- const idSet = new Set(matches.map((m) => m.id));
144
- const matched = this.episodes.filter((e) => idSet.has(e.id));
145
- // Sort by Pinecone score order (highest first), limit to topK
146
- const scoreMap = new Map(matches.map((m) => [m.id, m.score ?? 0]));
147
- return matched
148
- .sort((a, b) => (scoreMap.get(b.id) ?? 0) - (scoreMap.get(a.id) ?? 0))
149
- .slice(0, topK);
150
- }
151
- async getByIds(ids) {
152
- this.ensureInitialized();
153
- const idSet = new Set(ids);
154
- return this.episodes.filter((e) => idSet.has(e.id));
155
- }
156
- async countEpisodes(query) {
157
- this.ensureInitialized();
158
- let results = this.episodes;
159
- if (query.sourceEntity) {
160
- results = results.filter((e) => e.sourceEntity === query.sourceEntity);
161
- }
162
- if (query.context) {
163
- const ctx = query.context.toLowerCase();
164
- results = results.filter((e) => e.context && e.context.toLowerCase().includes(ctx));
165
- }
166
- if (query.timeRange) {
167
- const [start, end] = query.timeRange;
168
- results = results.filter((e) => e.timestamp >= start && e.timestamp <= end);
169
- }
170
- return results.length;
171
- }
172
- async updateEpisode(id, patch) {
173
- this.ensureInitialized();
174
- const episode = this.episodes.find((e) => e.id === id);
175
- if (!episode)
176
- return;
177
- if (patch.importance !== undefined)
178
- episode.importance = patch.importance;
179
- if (patch.intensity !== undefined)
180
- episode.intensity = patch.intensity;
181
- if (patch.emotionSnapshot !== undefined)
182
- episode.emotionSnapshot = patch.emotionSnapshot;
183
- }
184
- async deleteEpisode(id) {
185
- this.ensureInitialized();
186
- this.episodes = this.episodes.filter((e) => e.id !== id);
187
- // Best-effort Pinecone cleanup
188
- try {
189
- await this.ns().deleteOne(id);
190
- }
191
- catch {
192
- // Non-fatal: Pinecone cleanup failure doesn't affect in-memory state.
193
- }
194
- }
195
- async expireEpisodes(before, minImportance) {
196
- this.ensureInitialized();
197
- const threshold = minImportance ?? 0;
198
- const original = this.episodes.length;
199
- // Collect IDs of episodes to expire for Pinecone cleanup
200
- const expiredIds = this.episodes
201
- .filter((e) => e.timestamp < before && e.importance < threshold)
202
- .map((e) => e.id);
203
- this.episodes = this.episodes.filter((e) => e.timestamp >= before || e.importance >= threshold);
204
- const count = original - this.episodes.length;
205
- // Best-effort Pinecone cleanup
206
- if (expiredIds.length > 0) {
207
- try {
208
- await this.ns().deleteMany({ ids: expiredIds });
209
- }
210
- catch {
211
- // Non-fatal: Pinecone cleanup failure doesn't affect in-memory state.
212
- }
213
- }
214
- return count;
215
- }
216
- }