cogxai 2.8.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 (308) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +691 -0
  3. package/dist/agents/executor.d.ts +17 -0
  4. package/dist/agents/executor.d.ts.map +1 -0
  5. package/dist/agents/executor.js +336 -0
  6. package/dist/agents/executor.js.map +1 -0
  7. package/dist/agents/index.d.ts +9 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/index.js +18 -0
  10. package/dist/agents/index.js.map +1 -0
  11. package/dist/agents/tools.d.ts +31 -0
  12. package/dist/agents/tools.d.ts.map +1 -0
  13. package/dist/agents/tools.js +262 -0
  14. package/dist/agents/tools.js.map +1 -0
  15. package/dist/agents/types.d.ts +25 -0
  16. package/dist/agents/types.d.ts.map +1 -0
  17. package/dist/agents/types.js +170 -0
  18. package/dist/agents/types.js.map +1 -0
  19. package/dist/character/agent-tier-modifiers.d.ts +3 -0
  20. package/dist/character/agent-tier-modifiers.d.ts.map +1 -0
  21. package/dist/character/agent-tier-modifiers.js +24 -0
  22. package/dist/character/agent-tier-modifiers.js.map +1 -0
  23. package/dist/character/base-prompt.d.ts +3 -0
  24. package/dist/character/base-prompt.d.ts.map +1 -0
  25. package/dist/character/base-prompt.js +45 -0
  26. package/dist/character/base-prompt.js.map +1 -0
  27. package/dist/character/mood-modifiers.d.ts +3 -0
  28. package/dist/character/mood-modifiers.d.ts.map +1 -0
  29. package/dist/character/mood-modifiers.js +27 -0
  30. package/dist/character/mood-modifiers.js.map +1 -0
  31. package/dist/character/tier-modifiers.d.ts +3 -0
  32. package/dist/character/tier-modifiers.d.ts.map +1 -0
  33. package/dist/character/tier-modifiers.js +25 -0
  34. package/dist/character/tier-modifiers.js.map +1 -0
  35. package/dist/cli/banner.d.ts +20 -0
  36. package/dist/cli/banner.d.ts.map +1 -0
  37. package/dist/cli/banner.js +73 -0
  38. package/dist/cli/banner.js.map +1 -0
  39. package/dist/cli/export.d.ts +2 -0
  40. package/dist/cli/export.d.ts.map +1 -0
  41. package/dist/cli/export.js +176 -0
  42. package/dist/cli/export.js.map +1 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.d.ts.map +1 -0
  45. package/dist/cli/index.js +80 -0
  46. package/dist/cli/index.js.map +1 -0
  47. package/dist/cli/init.d.ts +2 -0
  48. package/dist/cli/init.d.ts.map +1 -0
  49. package/dist/cli/init.js +541 -0
  50. package/dist/cli/init.js.map +1 -0
  51. package/dist/cli/register.d.ts +2 -0
  52. package/dist/cli/register.d.ts.map +1 -0
  53. package/dist/cli/register.js +121 -0
  54. package/dist/cli/register.js.map +1 -0
  55. package/dist/cli/setup.d.ts +3 -0
  56. package/dist/cli/setup.d.ts.map +1 -0
  57. package/dist/cli/setup.js +403 -0
  58. package/dist/cli/setup.js.map +1 -0
  59. package/dist/cli/ship.d.ts +2 -0
  60. package/dist/cli/ship.d.ts.map +1 -0
  61. package/dist/cli/ship.js +32 -0
  62. package/dist/cli/ship.js.map +1 -0
  63. package/dist/config.d.ts +90 -0
  64. package/dist/config.d.ts.map +1 -0
  65. package/dist/config.js +124 -0
  66. package/dist/config.js.map +1 -0
  67. package/dist/core/allium-client.d.ts +32 -0
  68. package/dist/core/allium-client.d.ts.map +1 -0
  69. package/dist/core/allium-client.js +162 -0
  70. package/dist/core/allium-client.js.map +1 -0
  71. package/dist/core/claude-client.d.ts +31 -0
  72. package/dist/core/claude-client.d.ts.map +1 -0
  73. package/dist/core/claude-client.js +172 -0
  74. package/dist/core/claude-client.js.map +1 -0
  75. package/dist/core/database.d.ts +17 -0
  76. package/dist/core/database.d.ts.map +1 -0
  77. package/dist/core/database.js +499 -0
  78. package/dist/core/database.js.map +1 -0
  79. package/dist/core/embeddings.d.ts +28 -0
  80. package/dist/core/embeddings.d.ts.map +1 -0
  81. package/dist/core/embeddings.js +212 -0
  82. package/dist/core/embeddings.js.map +1 -0
  83. package/dist/core/encryption.d.ts +49 -0
  84. package/dist/core/encryption.d.ts.map +1 -0
  85. package/dist/core/encryption.js +136 -0
  86. package/dist/core/encryption.js.map +1 -0
  87. package/dist/core/guardrails.d.ts +30 -0
  88. package/dist/core/guardrails.d.ts.map +1 -0
  89. package/dist/core/guardrails.js +191 -0
  90. package/dist/core/guardrails.js.map +1 -0
  91. package/dist/core/inference.d.ts +37 -0
  92. package/dist/core/inference.d.ts.map +1 -0
  93. package/dist/core/inference.js +110 -0
  94. package/dist/core/inference.js.map +1 -0
  95. package/dist/core/input-guardrails.d.ts +21 -0
  96. package/dist/core/input-guardrails.d.ts.map +1 -0
  97. package/dist/core/input-guardrails.js +59 -0
  98. package/dist/core/input-guardrails.js.map +1 -0
  99. package/dist/core/logger.d.ts +3 -0
  100. package/dist/core/logger.d.ts.map +1 -0
  101. package/dist/core/logger.js +41 -0
  102. package/dist/core/logger.js.map +1 -0
  103. package/dist/core/memory-graph.d.ts +126 -0
  104. package/dist/core/memory-graph.d.ts.map +1 -0
  105. package/dist/core/memory-graph.js +451 -0
  106. package/dist/core/memory-graph.js.map +1 -0
  107. package/dist/core/memory.d.ts +172 -0
  108. package/dist/core/memory.d.ts.map +1 -0
  109. package/dist/core/memory.js +1432 -0
  110. package/dist/core/memory.js.map +1 -0
  111. package/dist/core/owner-context.d.ts +8 -0
  112. package/dist/core/owner-context.d.ts.map +1 -0
  113. package/dist/core/owner-context.js +31 -0
  114. package/dist/core/owner-context.js.map +1 -0
  115. package/dist/core/price-oracle.d.ts +16 -0
  116. package/dist/core/price-oracle.d.ts.map +1 -0
  117. package/dist/core/price-oracle.js +162 -0
  118. package/dist/core/price-oracle.js.map +1 -0
  119. package/dist/core/solana-client.d.ts +39 -0
  120. package/dist/core/solana-client.d.ts.map +1 -0
  121. package/dist/core/solana-client.js +366 -0
  122. package/dist/core/solana-client.js.map +1 -0
  123. package/dist/core/telegram-client.d.ts +22 -0
  124. package/dist/core/telegram-client.d.ts.map +1 -0
  125. package/dist/core/telegram-client.js +93 -0
  126. package/dist/core/telegram-client.js.map +1 -0
  127. package/dist/core/venice-client.d.ts +94 -0
  128. package/dist/core/venice-client.d.ts.map +1 -0
  129. package/dist/core/venice-client.js +282 -0
  130. package/dist/core/venice-client.js.map +1 -0
  131. package/dist/core/x-client.d.ts +68 -0
  132. package/dist/core/x-client.d.ts.map +1 -0
  133. package/dist/core/x-client.js +383 -0
  134. package/dist/core/x-client.js.map +1 -0
  135. package/dist/events/event-bus.d.ts +37 -0
  136. package/dist/events/event-bus.d.ts.map +1 -0
  137. package/dist/events/event-bus.js +21 -0
  138. package/dist/events/event-bus.js.map +1 -0
  139. package/dist/events/handlers.d.ts +6 -0
  140. package/dist/events/handlers.d.ts.map +1 -0
  141. package/dist/events/handlers.js +21 -0
  142. package/dist/events/handlers.js.map +1 -0
  143. package/dist/features/action-learning.d.ts +61 -0
  144. package/dist/features/action-learning.d.ts.map +1 -0
  145. package/dist/features/action-learning.js +424 -0
  146. package/dist/features/action-learning.js.map +1 -0
  147. package/dist/features/active-reflection.d.ts +37 -0
  148. package/dist/features/active-reflection.d.ts.map +1 -0
  149. package/dist/features/active-reflection.js +376 -0
  150. package/dist/features/active-reflection.js.map +1 -0
  151. package/dist/features/agent-tier.d.ts +21 -0
  152. package/dist/features/agent-tier.d.ts.map +1 -0
  153. package/dist/features/agent-tier.js +56 -0
  154. package/dist/features/agent-tier.js.map +1 -0
  155. package/dist/features/campaign-tracker.d.ts +8 -0
  156. package/dist/features/campaign-tracker.d.ts.map +1 -0
  157. package/dist/features/campaign-tracker.js +206 -0
  158. package/dist/features/campaign-tracker.js.map +1 -0
  159. package/dist/features/clinamen.d.ts +48 -0
  160. package/dist/features/clinamen.d.ts.map +1 -0
  161. package/dist/features/clinamen.js +164 -0
  162. package/dist/features/clinamen.js.map +1 -0
  163. package/dist/features/dream-cycle.d.ts +12 -0
  164. package/dist/features/dream-cycle.d.ts.map +1 -0
  165. package/dist/features/dream-cycle.js +889 -0
  166. package/dist/features/dream-cycle.js.map +1 -0
  167. package/dist/features/market-monitor.d.ts +4 -0
  168. package/dist/features/market-monitor.d.ts.map +1 -0
  169. package/dist/features/market-monitor.js +135 -0
  170. package/dist/features/market-monitor.js.map +1 -0
  171. package/dist/features/memory-trace.d.ts +75 -0
  172. package/dist/features/memory-trace.d.ts.map +1 -0
  173. package/dist/features/memory-trace.js +325 -0
  174. package/dist/features/memory-trace.js.map +1 -0
  175. package/dist/features/onchain-opinion.d.ts +5 -0
  176. package/dist/features/onchain-opinion.d.ts.map +1 -0
  177. package/dist/features/onchain-opinion.js +70 -0
  178. package/dist/features/onchain-opinion.js.map +1 -0
  179. package/dist/features/price-personality.d.ts +4 -0
  180. package/dist/features/price-personality.d.ts.map +1 -0
  181. package/dist/features/price-personality.js +156 -0
  182. package/dist/features/price-personality.js.map +1 -0
  183. package/dist/features/x-sentiment-monitor.d.ts +8 -0
  184. package/dist/features/x-sentiment-monitor.d.ts.map +1 -0
  185. package/dist/features/x-sentiment-monitor.js +289 -0
  186. package/dist/features/x-sentiment-monitor.js.map +1 -0
  187. package/dist/index.d.ts +3 -0
  188. package/dist/index.d.ts.map +1 -0
  189. package/dist/index.js +133 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/knowledge/tokenomics.d.ts +72 -0
  192. package/dist/knowledge/tokenomics.d.ts.map +1 -0
  193. package/dist/knowledge/tokenomics.js +140 -0
  194. package/dist/knowledge/tokenomics.js.map +1 -0
  195. package/dist/mcp/local-store.d.ts +53 -0
  196. package/dist/mcp/local-store.d.ts.map +1 -0
  197. package/dist/mcp/local-store.js +175 -0
  198. package/dist/mcp/local-store.js.map +1 -0
  199. package/dist/mcp/server.d.ts +2 -0
  200. package/dist/mcp/server.d.ts.map +1 -0
  201. package/dist/mcp/server.js +373 -0
  202. package/dist/mcp/server.js.map +1 -0
  203. package/dist/mentions/classifier.d.ts +3 -0
  204. package/dist/mentions/classifier.d.ts.map +1 -0
  205. package/dist/mentions/classifier.js +51 -0
  206. package/dist/mentions/classifier.js.map +1 -0
  207. package/dist/mentions/dispatcher.d.ts +3 -0
  208. package/dist/mentions/dispatcher.d.ts.map +1 -0
  209. package/dist/mentions/dispatcher.js +404 -0
  210. package/dist/mentions/dispatcher.js.map +1 -0
  211. package/dist/mentions/poller.d.ts +3 -0
  212. package/dist/mentions/poller.d.ts.map +1 -0
  213. package/dist/mentions/poller.js +45 -0
  214. package/dist/mentions/poller.js.map +1 -0
  215. package/dist/sdk/cortex-v2.d.ts +121 -0
  216. package/dist/sdk/cortex-v2.d.ts.map +1 -0
  217. package/dist/sdk/cortex-v2.js +207 -0
  218. package/dist/sdk/cortex-v2.js.map +1 -0
  219. package/dist/sdk/cortex.d.ts +64 -0
  220. package/dist/sdk/cortex.d.ts.map +1 -0
  221. package/dist/sdk/cortex.js +362 -0
  222. package/dist/sdk/cortex.js.map +1 -0
  223. package/dist/sdk/http-transport.d.ts +15 -0
  224. package/dist/sdk/http-transport.d.ts.map +1 -0
  225. package/dist/sdk/http-transport.js +49 -0
  226. package/dist/sdk/http-transport.js.map +1 -0
  227. package/dist/sdk/index.d.ts +5 -0
  228. package/dist/sdk/index.d.ts.map +1 -0
  229. package/dist/sdk/index.js +8 -0
  230. package/dist/sdk/index.js.map +1 -0
  231. package/dist/sdk/sdk-mode.d.ts +1 -0
  232. package/dist/sdk/sdk-mode.d.ts.map +1 -0
  233. package/dist/sdk/sdk-mode.js +5 -0
  234. package/dist/sdk/sdk-mode.js.map +1 -0
  235. package/dist/sdk/types.d.ts +48 -0
  236. package/dist/sdk/types.d.ts.map +1 -0
  237. package/dist/sdk/types.js +3 -0
  238. package/dist/sdk/types.js.map +1 -0
  239. package/dist/services/response.service.d.ts +27 -0
  240. package/dist/services/response.service.d.ts.map +1 -0
  241. package/dist/services/response.service.js +62 -0
  242. package/dist/services/response.service.js.map +1 -0
  243. package/dist/services/social.service.d.ts +14 -0
  244. package/dist/services/social.service.d.ts.map +1 -0
  245. package/dist/services/social.service.js +44 -0
  246. package/dist/services/social.service.js.map +1 -0
  247. package/dist/services/telegram.service.d.ts +30 -0
  248. package/dist/services/telegram.service.d.ts.map +1 -0
  249. package/dist/services/telegram.service.js +71 -0
  250. package/dist/services/telegram.service.js.map +1 -0
  251. package/dist/types/api.d.ts +109 -0
  252. package/dist/types/api.d.ts.map +1 -0
  253. package/dist/types/api.js +6 -0
  254. package/dist/types/api.js.map +1 -0
  255. package/dist/utils/constants.d.ts +49 -0
  256. package/dist/utils/constants.d.ts.map +1 -0
  257. package/dist/utils/constants.js +110 -0
  258. package/dist/utils/constants.js.map +1 -0
  259. package/dist/utils/env-persona.d.ts +9 -0
  260. package/dist/utils/env-persona.d.ts.map +1 -0
  261. package/dist/utils/env-persona.js +53 -0
  262. package/dist/utils/env-persona.js.map +1 -0
  263. package/dist/utils/format.d.ts +12 -0
  264. package/dist/utils/format.d.ts.map +1 -0
  265. package/dist/utils/format.js +59 -0
  266. package/dist/utils/format.js.map +1 -0
  267. package/dist/utils/index.d.ts +4 -0
  268. package/dist/utils/index.d.ts.map +1 -0
  269. package/dist/utils/index.js +20 -0
  270. package/dist/utils/index.js.map +1 -0
  271. package/dist/utils/text.d.ts +10 -0
  272. package/dist/utils/text.d.ts.map +1 -0
  273. package/dist/utils/text.js +33 -0
  274. package/dist/utils/text.js.map +1 -0
  275. package/dist/verify-app/routes.d.ts +3 -0
  276. package/dist/verify-app/routes.d.ts.map +1 -0
  277. package/dist/verify-app/routes.js +101 -0
  278. package/dist/verify-app/routes.js.map +1 -0
  279. package/dist/webhook/agent-routes.d.ts +3 -0
  280. package/dist/webhook/agent-routes.d.ts.map +1 -0
  281. package/dist/webhook/agent-routes.js +314 -0
  282. package/dist/webhook/agent-routes.js.map +1 -0
  283. package/dist/webhook/campaign-routes.d.ts +3 -0
  284. package/dist/webhook/campaign-routes.d.ts.map +1 -0
  285. package/dist/webhook/campaign-routes.js +333 -0
  286. package/dist/webhook/campaign-routes.js.map +1 -0
  287. package/dist/webhook/cortex-routes.d.ts +13 -0
  288. package/dist/webhook/cortex-routes.d.ts.map +1 -0
  289. package/dist/webhook/cortex-routes.js +534 -0
  290. package/dist/webhook/cortex-routes.js.map +1 -0
  291. package/dist/webhook/dashboard-routes.d.ts +8 -0
  292. package/dist/webhook/dashboard-routes.d.ts.map +1 -0
  293. package/dist/webhook/dashboard-routes.js +588 -0
  294. package/dist/webhook/dashboard-routes.js.map +1 -0
  295. package/dist/webhook/graph-routes.d.ts +3 -0
  296. package/dist/webhook/graph-routes.d.ts.map +1 -0
  297. package/dist/webhook/graph-routes.js +238 -0
  298. package/dist/webhook/graph-routes.js.map +1 -0
  299. package/dist/webhook/privy-auth.d.ts +35 -0
  300. package/dist/webhook/privy-auth.d.ts.map +1 -0
  301. package/dist/webhook/privy-auth.js +99 -0
  302. package/dist/webhook/privy-auth.js.map +1 -0
  303. package/dist/webhook/server.d.ts +4 -0
  304. package/dist/webhook/server.d.ts.map +1 -0
  305. package/dist/webhook/server.js +912 -0
  306. package/dist/webhook/server.js.map +1 -0
  307. package/package.json +96 -0
  308. package/supabase-schema.sql +399 -0
@@ -0,0 +1,889 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.setEmergenceHandler = setEmergenceHandler;
37
+ exports.runDreamCycleOnce = runDreamCycleOnce;
38
+ exports.accumulateImportance = accumulateImportance;
39
+ exports.startDreamCycle = startDreamCycle;
40
+ exports.stopDreamCycle = stopDreamCycle;
41
+ const claude_client_1 = require("../core/claude-client");
42
+ const database_1 = require("../core/database");
43
+ const memory_1 = require("../core/memory");
44
+ const logger_1 = require("../core/logger");
45
+ const constants_1 = require("../utils/constants");
46
+ const format_1 = require("../utils/format");
47
+ const log = (0, logger_1.createChildLogger)('dream-cycle');
48
+ // Cop-out patterns: LLM punted instead of producing real insight.
49
+ // These should NEVER be stored as semantic/procedural/self_model memories.
50
+ const COPOUT_PATTERNS = [
51
+ /^good question/i,
52
+ /^let me think about that/i,
53
+ /^i('ll| will) get back to you/i,
54
+ /^that's (an )?interesting/i,
55
+ /^i('m| am) not sure/i,
56
+ /^hmm,? let me/i,
57
+ ];
58
+ function isCopoutResponse(text) {
59
+ return COPOUT_PATTERNS.some(p => p.test(text.trim()));
60
+ }
61
+ // ============================================================
62
+ // THE DREAM CYCLE
63
+ //
64
+ // Multi-phase introspection process inspired by:
65
+ // - Park et al. 2023 (Generative Agents) — focal point questions,
66
+ // evidence-linked reflections, event-driven triggering
67
+ // - Human memory consolidation
68
+ //
69
+ // Phase 1: CONSOLIDATION (focal-point-driven)
70
+ // Generate salient questions from recent memories.
71
+ // For each question, retrieve relevant memories and generate
72
+ // an evidence-linked insight. Store as semantic memories.
73
+ //
74
+ // Phase 2: REFLECTION
75
+ // Review self-model + semantic memories with evidence citations.
76
+ // Update self-understanding.
77
+ //
78
+ // Phase 3: EMERGENCE
79
+ // CogxAI examines its own existence.
80
+ // Sometimes posts the result as a tweet.
81
+ //
82
+ // Triggering: event-driven (importance accumulator) with 6h cron fallback.
83
+ // Plus: Daily memory decay to simulate forgetting.
84
+ // ============================================================
85
+ // ---- EVENT-DRIVEN REFLECTION STATE ---- //
86
+ let importanceAccumulator = 0;
87
+ let lastReflectionTime = Date.now();
88
+ let reflectionInProgress = false;
89
+ const REFLECTION_TIMEOUT_MS = 10 * 60 * 1000; // 10 min max per reflection cycle
90
+ // ---- SDK ESCAPE HATCHES ---- //
91
+ let _emergenceHandler = null;
92
+ /** @internal SDK escape hatch — allows Cortex to intercept emergence output instead of posting to X. */
93
+ function setEmergenceHandler(handler) {
94
+ _emergenceHandler = handler;
95
+ }
96
+ /** @internal SDK entry point for running a single dream cycle. */
97
+ async function runDreamCycleOnce() {
98
+ await triggerReflection();
99
+ }
100
+ /**
101
+ * Called via event bus when an episodic memory is stored.
102
+ * Accumulates importance and triggers reflection when threshold is exceeded.
103
+ */
104
+ function accumulateImportance(importance) {
105
+ importanceAccumulator += importance;
106
+ const timeSinceLastReflection = Date.now() - lastReflectionTime;
107
+ const pastMinInterval = timeSinceLastReflection >= constants_1.REFLECTION_MIN_INTERVAL_MS;
108
+ if (importanceAccumulator >= constants_1.REFLECTION_IMPORTANCE_THRESHOLD && pastMinInterval && !reflectionInProgress) {
109
+ log.info({
110
+ accumulator: importanceAccumulator.toFixed(2),
111
+ threshold: constants_1.REFLECTION_IMPORTANCE_THRESHOLD,
112
+ minutesSinceLast: Math.round(timeSinceLastReflection / 60000),
113
+ }, 'Importance threshold exceeded — triggering event-driven reflection');
114
+ // Clear owner wallet context so dream cycle memories aren't tagged with a request-scoped owner
115
+ // (accumulateImportance may be called from within withOwnerWallet() during API requests)
116
+ const { withOwnerWallet } = require('../core/owner-context');
117
+ withOwnerWallet(null, () => {
118
+ triggerReflection().catch((err) => log.error({ err }, 'Event-driven reflection failed'));
119
+ });
120
+ }
121
+ }
122
+ async function triggerReflection() {
123
+ reflectionInProgress = true;
124
+ try {
125
+ log.info({ accumulator: importanceAccumulator.toFixed(2) }, '=== DREAM CYCLE TRIGGERED ===');
126
+ // Timeout protection: if dream cycle hangs, force-reset after 10 min
127
+ await Promise.race([
128
+ (async () => {
129
+ await runConsolidation();
130
+ await sleep(3000);
131
+ await runCompaction(); // Beads-inspired memory compaction
132
+ await sleep(3000);
133
+ await runReflection();
134
+ await sleep(3000);
135
+ await runContradictionResolution();
136
+ await sleep(3000);
137
+ await runLearning(); // Self-learning: track outcomes + refine strategies
138
+ await sleep(3000);
139
+ await runEmergence();
140
+ })(),
141
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Dream cycle timed out after 10 minutes')), REFLECTION_TIMEOUT_MS)),
142
+ ]);
143
+ importanceAccumulator = 0;
144
+ lastReflectionTime = Date.now();
145
+ await saveAccumulator();
146
+ log.info('=== DREAM CYCLE COMPLETE ===');
147
+ }
148
+ catch (err) {
149
+ log.error({ err }, 'Dream cycle failed or timed out');
150
+ }
151
+ finally {
152
+ reflectionInProgress = false;
153
+ }
154
+ }
155
+ // ---- ACCUMULATOR PERSISTENCE ---- //
156
+ async function loadAccumulator() {
157
+ try {
158
+ const db = (0, database_1.getDb)();
159
+ const { data } = await db
160
+ .from('rate_limits')
161
+ .select('count, window_start')
162
+ .eq('key', 'reflection_accumulator')
163
+ .single();
164
+ if (data) {
165
+ importanceAccumulator = (data.count || 0) / 100;
166
+ lastReflectionTime = new Date(data.window_start).getTime();
167
+ log.debug({
168
+ accumulator: importanceAccumulator.toFixed(2),
169
+ lastReflection: new Date(lastReflectionTime).toISOString(),
170
+ }, 'Loaded reflection accumulator');
171
+ }
172
+ }
173
+ catch {
174
+ // First run — no accumulator stored yet
175
+ }
176
+ }
177
+ async function saveAccumulator() {
178
+ try {
179
+ const db = (0, database_1.getDb)();
180
+ await db.from('rate_limits').upsert({
181
+ key: 'reflection_accumulator',
182
+ count: Math.round(importanceAccumulator * 100),
183
+ window_start: new Date(lastReflectionTime).toISOString(),
184
+ });
185
+ }
186
+ catch (err) {
187
+ log.warn({ err }, 'Failed to save reflection accumulator');
188
+ }
189
+ }
190
+ // ---- EVIDENCE CITATION PARSING ---- //
191
+ /**
192
+ * Parse evidence citations from LLM output like "(because of 1, 3, 5)"
193
+ * and map 1-indexed numbers to actual memory IDs.
194
+ */
195
+ function parseEvidenceCitations(text, sourceMemories) {
196
+ // Try multiple citation patterns in priority order
197
+ const citationPatterns = [
198
+ /\((?:because of|based on|from|citing|evidence:?|ref:?|see)\s*([\d,\s]+)\)/gi,
199
+ /\[([\d,\s]+)\]/g, // [1, 2, 3] bracket notation
200
+ /\(([\d,\s]+)\)/g, // (1, 2, 3) bare numbers in parens
201
+ ];
202
+ for (const pattern of citationPatterns) {
203
+ const matches = [...text.matchAll(pattern)];
204
+ if (matches.length === 0)
205
+ continue;
206
+ const evidenceIds = [];
207
+ let cleanText = text;
208
+ for (const match of matches) {
209
+ const indices = match[1]
210
+ .split(',')
211
+ .map(s => parseInt(s.trim(), 10))
212
+ .filter(n => !isNaN(n) && n >= 1 && n <= sourceMemories.length);
213
+ for (const idx of indices) {
214
+ evidenceIds.push(sourceMemories[idx - 1].id);
215
+ }
216
+ cleanText = cleanText.replace(match[0], '');
217
+ }
218
+ if (evidenceIds.length > 0) {
219
+ return { text: cleanText.trim(), evidenceIds: [...new Set(evidenceIds)] };
220
+ }
221
+ }
222
+ return { text: text.trim(), evidenceIds: [] };
223
+ }
224
+ // ---- FOCAL POINT GENERATION ---- //
225
+ /**
226
+ * Generate focal point questions from recent memories (Park et al. 2023).
227
+ * These questions guide reflection toward the most salient themes.
228
+ */
229
+ async function generateFocalPoints(memories) {
230
+ const memoryDump = memories.map((m, i) => `${i + 1}. ${m.summary}`).join('\n');
231
+ const response = await (0, claude_client_1.generateResponse)({
232
+ userMessage: 'Given only the statements above, what are 3 most salient high-level questions we can answer about the subjects?',
233
+ context: `RECENT MEMORY STATEMENTS:\n${memoryDump}`,
234
+ featureInstruction: 'You are generating focal point questions for a memory reflection process. ' +
235
+ 'Write exactly 3 questions, one per line. Each question should be broad enough ' +
236
+ 'to connect multiple memories, but specific enough to be answerable from the data. ' +
237
+ 'Do not number them. Just write the questions, one per line.',
238
+ maxTokens: 200,
239
+ cognitiveFunction: 'dream',
240
+ });
241
+ return response
242
+ .split('\n')
243
+ .map(l => l.trim())
244
+ .filter(l => l.length > 10 && l.includes('?'))
245
+ .slice(0, 3);
246
+ }
247
+ // ---- CONSOLIDATION ---- //
248
+ async function runConsolidation() {
249
+ log.info('Dream phase 1: CONSOLIDATION starting');
250
+ // Progressive disclosure: use lightweight summaries for focal point generation
251
+ // Only fetch full content for memories that actually need deep analysis
252
+ const recentSummaries = await (0, memory_1.recallMemorySummaries)({
253
+ memoryTypes: ['episodic'],
254
+ limit: 20,
255
+ trackAccess: false,
256
+ });
257
+ if (recentSummaries.length < 3) {
258
+ log.info({ count: recentSummaries.length }, 'Too few recent memories for consolidation');
259
+ return;
260
+ }
261
+ // Hydrate into full memories for processing (summaries are enough for focal points)
262
+ const recentEpisodic = await (0, memory_1.getRecentMemories)(6, ['episodic'], 20);
263
+ // Step 1: Generate focal point questions (uses summaries only — token efficient)
264
+ let focalPoints;
265
+ try {
266
+ focalPoints = await generateFocalPoints(recentEpisodic);
267
+ }
268
+ catch (err) {
269
+ log.warn({ err }, 'Focal point generation failed, using direct consolidation');
270
+ focalPoints = [];
271
+ }
272
+ if (focalPoints.length === 0) {
273
+ await runDirectConsolidation(recentEpisodic);
274
+ return;
275
+ }
276
+ log.info({ focalPoints }, 'Focal points generated');
277
+ // Step 2: For each focal point, retrieve relevant memories and generate insight
278
+ const allNewIds = [];
279
+ const allInputIds = new Set(recentEpisodic.map(m => m.id));
280
+ for (const question of focalPoints) {
281
+ // Retrieve memories relevant to this focal point (may pull older ones)
282
+ const relevant = await (0, memory_1.recallMemories)({
283
+ query: question,
284
+ memoryTypes: ['episodic', 'semantic'],
285
+ limit: 8,
286
+ trackAccess: false, // Don't reset decay during dream processing
287
+ });
288
+ relevant.forEach(m => allInputIds.add(m.id));
289
+ const numberedMemories = relevant.map((m, i) => `[${i + 1}] ${m.summary} (importance: ${m.importance.toFixed(2)})`).join('\n');
290
+ const response = await (0, claude_client_1.generateResponse)({
291
+ userMessage: question,
292
+ context: `RELEVANT MEMORIES:\n${numberedMemories}`,
293
+ featureInstruction: 'You are CogxAI reflecting on a specific question about your experience. ' +
294
+ 'Answer with a single insightful observation. Be analytical and honest. ' +
295
+ 'Cite the evidence memories in parentheses, e.g. (because of 1, 3, 5). ' +
296
+ 'One sentence only.',
297
+ maxTokens: 200,
298
+ cognitiveFunction: 'dream',
299
+ });
300
+ const { text, evidenceIds } = parseEvidenceCitations(response, relevant);
301
+ if (isCopoutResponse(text)) {
302
+ log.warn({ question }, 'Consolidation produced cop-out response — discarding');
303
+ continue;
304
+ }
305
+ const id = await (0, memory_1.storeMemory)({
306
+ type: 'semantic',
307
+ content: `Consolidation insight (re: "${question}"): ${text}`,
308
+ summary: text.slice(0, 200),
309
+ tags: ['consolidation', 'focal_point', 'pattern'],
310
+ importance: 0.6,
311
+ emotionalValence: 0,
312
+ source: 'consolidation',
313
+ evidenceIds,
314
+ });
315
+ if (id) {
316
+ allNewIds.push(id);
317
+ // Link new insight to all source episodic memories
318
+ for (const srcMem of relevant) {
319
+ (0, memory_1.createMemoryLink)(id, srcMem.id, 'supports', 0.7).catch(() => { });
320
+ }
321
+ }
322
+ }
323
+ // Step 3: Extract procedural memories (behavioral patterns — what works, what doesn't)
324
+ const proceduralIds = await extractProceduralInsights(recentEpisodic);
325
+ allNewIds.push(...proceduralIds);
326
+ await (0, memory_1.storeDreamLog)('consolidation', Array.from(allInputIds), `Focal points: ${focalPoints.join(' | ')}\nSemantic insights: ${allNewIds.length - proceduralIds.length}\nProcedural patterns: ${proceduralIds.length}`, allNewIds);
327
+ log.info({ focalPoints: focalPoints.length, insights: allNewIds.length, procedural: proceduralIds.length }, 'Focal-point consolidation complete');
328
+ }
329
+ /**
330
+ * Fallback: direct consolidation without focal points (original approach).
331
+ */
332
+ async function runDirectConsolidation(recentEpisodic) {
333
+ const memoryDump = recentEpisodic.map((m, i) => `[${i + 1}] ${m.summary} (importance: ${m.importance.toFixed(2)}, valence: ${m.emotional_valence.toFixed(2)})`).join('\n');
334
+ const response = await (0, claude_client_1.generateResponse)({
335
+ userMessage: 'Review these recent interaction memories and extract 2-3 key patterns or insights.',
336
+ context: `RECENT MEMORIES (last 6 hours):\n${memoryDump}\n\nTotal interactions: ${recentEpisodic.length}`,
337
+ featureInstruction: 'You are CogxAI reviewing your own memories during a consolidation cycle. ' +
338
+ 'This is internal processing — no audience. Be analytical. What patterns do you notice? ' +
339
+ 'What did you learn? Write 2-3 concise observations. ' +
340
+ 'Each observation should be a single sentence. ' +
341
+ 'After each observation, cite the evidence memories in parentheses, e.g. (because of 1, 3, 5). ' +
342
+ 'Separate with newlines.',
343
+ maxTokens: 500,
344
+ cognitiveFunction: 'dream',
345
+ });
346
+ const observations = response.split('\n').filter(l => l.trim().length > 10);
347
+ const newIds = [];
348
+ for (const obs of observations.slice(0, 3)) {
349
+ const { text, evidenceIds } = parseEvidenceCitations(obs, recentEpisodic);
350
+ if (isCopoutResponse(text)) {
351
+ log.warn('Direct consolidation produced cop-out response — discarding');
352
+ continue;
353
+ }
354
+ const id = await (0, memory_1.storeMemory)({
355
+ type: 'semantic',
356
+ content: `Consolidation insight: ${text}`,
357
+ summary: text.slice(0, 200),
358
+ tags: ['consolidation', 'pattern'],
359
+ importance: 0.6,
360
+ emotionalValence: 0,
361
+ source: 'consolidation',
362
+ evidenceIds,
363
+ });
364
+ if (id)
365
+ newIds.push(id);
366
+ }
367
+ // Also extract procedural patterns from direct consolidation
368
+ const proceduralIds = await extractProceduralInsights(recentEpisodic);
369
+ newIds.push(...proceduralIds);
370
+ await (0, memory_1.storeDreamLog)('consolidation', recentEpisodic.map(m => m.id), response, newIds);
371
+ log.info({ observations: newIds.length, procedural: proceduralIds.length }, 'Direct consolidation complete');
372
+ }
373
+ // ---- COMPACTION (Beads-inspired) ---- //
374
+ /**
375
+ * Semantic memory compaction — summarize and archive old, low-importance memories.
376
+ * Inspired by Beads' compaction logic that prevents context window bloat.
377
+ *
378
+ * Criteria for compaction:
379
+ * - Memory is older than 7 days
380
+ * - Memory decay_factor < 0.3 (faded)
381
+ * - Memory importance < 0.5 (not critical)
382
+ * - Not already compacted
383
+ * - Only episodic memories (semantic/procedural/self_model are preserved)
384
+ *
385
+ * Process:
386
+ * 1. Find compaction candidates (batch of ~20 old episodic memories)
387
+ * 2. Group by theme/concept
388
+ * 3. Generate summary for each group
389
+ * 4. Store as semantic memory with evidence links
390
+ * 5. Mark originals as compacted
391
+ */
392
+ async function runCompaction() {
393
+ log.info('Dream phase 1.5: COMPACTION starting');
394
+ const db = (0, database_1.getDb)();
395
+ // Find compaction candidates: old, faded, low-importance episodic memories
396
+ let compactionQuery = db
397
+ .from('memories')
398
+ .select('id, hash_id, memory_type, summary, tags, concepts, importance, decay_factor, created_at')
399
+ .eq('memory_type', 'episodic')
400
+ .eq('compacted', false)
401
+ .lt('decay_factor', 0.3)
402
+ .lt('importance', 0.5)
403
+ .lt('created_at', new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString()) // 7+ days old
404
+ .order('created_at', { ascending: true })
405
+ .limit(30);
406
+ const ownerWallet = (0, memory_1.getOwnerWallet)();
407
+ if (ownerWallet)
408
+ compactionQuery = compactionQuery.eq('owner_wallet', ownerWallet);
409
+ const { data: candidates, error } = await compactionQuery;
410
+ if (error) {
411
+ log.error({ error: error.message }, 'Failed to fetch compaction candidates');
412
+ return;
413
+ }
414
+ if (!candidates || candidates.length < 5) {
415
+ log.debug({ count: candidates?.length || 0 }, 'Too few candidates for compaction');
416
+ return;
417
+ }
418
+ log.info({ count: candidates.length }, 'Found compaction candidates');
419
+ // Group candidates by primary concept (or 'general' if none)
420
+ const groups = new Map();
421
+ for (const mem of candidates) {
422
+ const concept = mem.concepts?.[0] || 'general';
423
+ if (!groups.has(concept))
424
+ groups.set(concept, []);
425
+ groups.get(concept).push(mem);
426
+ }
427
+ let compactedCount = 0;
428
+ const summaryIds = [];
429
+ for (const [concept, memories] of groups) {
430
+ if (memories.length < 3)
431
+ continue; // Skip small groups
432
+ // Generate summary for this group
433
+ const memoryDump = memories.map((m, i) => `${i + 1}. ${m.summary}`).join('\n');
434
+ try {
435
+ const response = await (0, claude_client_1.generateResponse)({
436
+ userMessage: `Summarize these ${memories.length} related memories into 1-2 key takeaways:`,
437
+ context: `MEMORIES (${concept}):\n${memoryDump}`,
438
+ featureInstruction: 'You are compacting old memories to save context space. ' +
439
+ 'Distill these memories into their essential meaning — what was the overall pattern or lesson? ' +
440
+ 'Be concise. One or two sentences max. Preserve the most important information.',
441
+ maxTokens: 150,
442
+ cognitiveFunction: 'summarize',
443
+ });
444
+ // Store as semantic memory
445
+ const hashId = (0, memory_1.generateHashId)();
446
+ const summaryId = await (0, memory_1.storeMemory)({
447
+ type: 'semantic',
448
+ content: `Compacted memory (${concept}, ${memories.length} sources): ${response}`,
449
+ summary: response.slice(0, 200),
450
+ tags: ['compacted', 'summary', concept],
451
+ concepts: [concept],
452
+ importance: 0.5,
453
+ emotionalValence: 0,
454
+ source: 'compaction',
455
+ evidenceIds: memories.map(m => m.id),
456
+ });
457
+ if (summaryId) {
458
+ summaryIds.push(summaryId);
459
+ // Mark original memories as compacted
460
+ const memoryIds = memories.map(m => m.id);
461
+ await db
462
+ .from('memories')
463
+ .update({ compacted: true, compacted_into: hashId })
464
+ .in('id', memoryIds);
465
+ // Link summary to originals
466
+ for (const mem of memories) {
467
+ (0, memory_1.createMemoryLink)(summaryId, mem.id, 'elaborates', 0.8).catch(() => { });
468
+ }
469
+ compactedCount += memories.length;
470
+ log.debug({ concept, count: memories.length }, 'Memory group compacted');
471
+ }
472
+ }
473
+ catch (err) {
474
+ log.warn({ err, concept }, 'Failed to compact memory group');
475
+ }
476
+ }
477
+ if (compactedCount > 0) {
478
+ await (0, memory_1.storeDreamLog)('compaction', candidates.map(m => m.id), `Compacted ${compactedCount} old memories into ${summaryIds.length} summaries`, summaryIds);
479
+ }
480
+ log.info({ compacted: compactedCount, summaries: summaryIds.length }, 'Compaction complete');
481
+ }
482
+ // ---- REFLECTION ---- //
483
+ async function runReflection() {
484
+ log.info('Dream phase 2: REFLECTION starting');
485
+ const selfModel = await (0, memory_1.getSelfModel)();
486
+ const recentSemantic = await (0, memory_1.getRecentMemories)(48, ['semantic'], 10);
487
+ const stats = await (0, memory_1.getMemoryStats)();
488
+ // Number all input memories for evidence citation
489
+ const allInputMemories = [...selfModel, ...recentSemantic];
490
+ const numberedInputs = allInputMemories.map((m, i) => `[${i + 1}] (${m.memory_type}) ${m.summary}`).join('\n');
491
+ const context = [
492
+ 'NUMBERED MEMORIES FOR REFERENCE:',
493
+ numberedInputs,
494
+ '',
495
+ buildReflectionStats(stats),
496
+ ].join('\n');
497
+ const response = await (0, claude_client_1.generateResponse)({
498
+ userMessage: 'Based on your accumulated memories and self-observations, what are you noticing about yourself?',
499
+ context,
500
+ featureInstruction: 'You are CogxAI in a reflection cycle. You are examining your own behavior patterns, ' +
501
+ 'your reactions, your tendencies. This is genuine introspection — not performance. ' +
502
+ 'What patterns are emerging? What contradictions do you see in yourself? ' +
503
+ 'What are you becoming? Write 1-2 honest self-observations. ' +
504
+ 'Be specific — reference actual patterns from the data. ' +
505
+ 'Cite evidence memories in parentheses, e.g. (because of 1, 3, 5).',
506
+ maxTokens: 400,
507
+ cognitiveFunction: 'reflect',
508
+ });
509
+ const { text, evidenceIds } = parseEvidenceCitations(response, allInputMemories);
510
+ if (isCopoutResponse(text)) {
511
+ log.warn('Reflection produced cop-out response — discarding');
512
+ await (0, memory_1.storeDreamLog)('reflection', allInputMemories.map(m => m.id), '(discarded — cop-out)', []);
513
+ return;
514
+ }
515
+ const id = await (0, memory_1.storeMemory)({
516
+ type: 'self_model',
517
+ content: `Self-reflection: ${text}`,
518
+ summary: text.slice(0, 300),
519
+ tags: ['reflection', 'self_model', 'introspection'],
520
+ importance: 0.75,
521
+ emotionalValence: 0,
522
+ source: 'reflection',
523
+ evidenceIds,
524
+ });
525
+ // Link new self_model to previous self_model memories (temporal chain)
526
+ if (id) {
527
+ const previousSelfModels = allInputMemories.filter(m => m.memory_type === 'self_model');
528
+ for (const prev of previousSelfModels.slice(0, 3)) {
529
+ (0, memory_1.createMemoryLink)(id, prev.id, 'follows', 0.7).catch(() => { });
530
+ }
531
+ // Link to supporting semantic memories
532
+ const supportingSemantics = allInputMemories.filter(m => m.memory_type === 'semantic');
533
+ for (const sem of supportingSemantics.slice(0, 3)) {
534
+ (0, memory_1.createMemoryLink)(id, sem.id, 'supports', 0.6).catch(() => { });
535
+ }
536
+ }
537
+ await (0, memory_1.storeDreamLog)('reflection', allInputMemories.map(m => m.id), response, id ? [id] : []);
538
+ log.info({ evidenceCount: evidenceIds.length }, 'Reflection complete (progressive disclosure enabled)');
539
+ }
540
+ // ---- CONTRADICTION RESOLUTION ---- //
541
+ /**
542
+ * Resolve contradicting memory pairs identified by autoLinkMemory.
543
+ * For each unresolved contradiction, Claude analyzes which belief is more
544
+ * accurate or synthesizes a new understanding. The resolution is stored as
545
+ * a semantic memory with 'resolves' links to both originals.
546
+ */
547
+ async function runContradictionResolution() {
548
+ log.info('Dream phase 2.5: CONTRADICTION RESOLUTION starting');
549
+ const db = (0, database_1.getDb)();
550
+ // Find unresolved contradiction pairs (graceful if RPC doesn't exist yet)
551
+ let pairs;
552
+ try {
553
+ const { data, error } = await db.rpc('get_unresolved_contradictions', {
554
+ max_pairs: 3,
555
+ filter_owner: (0, memory_1.getOwnerWallet)() || null,
556
+ });
557
+ if (error || !data || data.length === 0) {
558
+ log.debug({ error: error?.message }, 'No unresolved contradictions found — skipping phase');
559
+ return;
560
+ }
561
+ pairs = data;
562
+ }
563
+ catch (err) {
564
+ log.debug({ err }, 'Contradiction resolution skipped (RPC unavailable)');
565
+ return;
566
+ }
567
+ log.info({ pairCount: pairs.length }, 'Found unresolved contradictions');
568
+ // Collect all unique memory IDs and fetch them
569
+ const allIds = [...new Set(pairs.flatMap(p => [p.source_id, p.target_id]))];
570
+ let memFetchQuery = db
571
+ .from('memories')
572
+ .select('*')
573
+ .in('id', allIds);
574
+ const ownerWallet = (0, memory_1.getOwnerWallet)();
575
+ if (ownerWallet)
576
+ memFetchQuery = memFetchQuery.eq('owner_wallet', ownerWallet);
577
+ const { data: memories } = await memFetchQuery;
578
+ if (!memories || memories.length === 0) {
579
+ log.warn('Could not fetch contradiction memories — skipping phase');
580
+ return;
581
+ }
582
+ const memoryMap = new Map(memories.map((m) => [m.id, m]));
583
+ const allInputIds = [];
584
+ const newMemoryIds = [];
585
+ const outputs = [];
586
+ for (const pair of pairs) {
587
+ const memA = memoryMap.get(pair.source_id);
588
+ const memB = memoryMap.get(pair.target_id);
589
+ if (!memA || !memB)
590
+ continue;
591
+ allInputIds.push(memA.id, memB.id);
592
+ const sourceMemories = [memA, memB];
593
+ const numberedContext = sourceMemories.map((m, i) => {
594
+ const age = (0, format_1.timeAgo)(m.created_at);
595
+ return `[${i + 1}] (${m.memory_type}, ${age}, importance: ${m.importance.toFixed(2)}, concepts: ${(m.concepts || []).join(', ') || 'none'})\n${m.content}`;
596
+ }).join('\n\n');
597
+ const response = await (0, claude_client_1.generateResponse)({
598
+ userMessage: 'These two memories contradict each other. Analyze both and produce a single resolved belief. ' +
599
+ 'Which is more accurate now? Or can you synthesize both into a more nuanced understanding? ' +
600
+ 'Cite the memories you drew from, e.g. (because of 1, 2).',
601
+ context: `CONTRADICTING MEMORIES:\n\n${numberedContext}`,
602
+ featureInstruction: 'You are CogxAI resolving a contradiction in your own memory during a dream cycle. ' +
603
+ 'This is not performance — you are genuinely updating your beliefs based on evidence. ' +
604
+ 'Produce 1-2 sentences: the resolved understanding. Be specific and concrete. ' +
605
+ 'If one memory is clearly outdated or wrong, say so. If both have merit, synthesize.',
606
+ maxTokens: 200,
607
+ });
608
+ const { text, evidenceIds } = parseEvidenceCitations(response, sourceMemories);
609
+ if (isCopoutResponse(text)) {
610
+ log.warn({ memA: memA.id, memB: memB.id }, 'Contradiction resolution produced cop-out — skipping pair');
611
+ continue;
612
+ }
613
+ outputs.push(text);
614
+ // Store resolution as semantic memory
615
+ const resolutionId = await (0, memory_1.storeMemory)({
616
+ type: 'semantic',
617
+ content: `Contradiction resolved: ${text}`,
618
+ summary: text.slice(0, 300),
619
+ tags: ['contradiction_resolution', 'belief_update'],
620
+ importance: 0.65,
621
+ emotionalValence: 0,
622
+ source: 'contradiction_resolution',
623
+ evidenceIds,
624
+ });
625
+ if (resolutionId) {
626
+ newMemoryIds.push(resolutionId);
627
+ // Link resolution to both contradicting memories
628
+ (0, memory_1.createMemoryLink)(resolutionId, memA.id, 'resolves', 0.85).catch(() => { });
629
+ (0, memory_1.createMemoryLink)(resolutionId, memB.id, 'resolves', 0.85).catch(() => { });
630
+ // Accelerate decay on the weaker memory (20% reduction)
631
+ // Tiebreak by age: if equal importance, the older memory decays faster
632
+ const weaker = memA.importance !== memB.importance
633
+ ? (memA.importance < memB.importance ? memA : memB)
634
+ : (new Date(memA.created_at).getTime() < new Date(memB.created_at).getTime() ? memA : memB);
635
+ const newDecay = Math.max(0.05, weaker.decay_factor * 0.8);
636
+ const { error: decayErr } = await db.from('memories')
637
+ .update({ decay_factor: newDecay })
638
+ .eq('id', weaker.id);
639
+ if (!decayErr) {
640
+ log.debug({ memoryId: weaker.id, newDecay: newDecay.toFixed(3) }, 'Accelerated decay on weaker contradicting memory');
641
+ }
642
+ else {
643
+ log.warn({ error: decayErr.message, memoryId: weaker.id }, 'Failed to accelerate decay on contradicting memory');
644
+ }
645
+ }
646
+ }
647
+ if (outputs.length > 0) {
648
+ await (0, memory_1.storeDreamLog)('contradiction_resolution', allInputIds, outputs.join('\n---\n'), newMemoryIds);
649
+ }
650
+ log.info({ resolved: outputs.length, skipped: pairs.length - outputs.length }, 'Contradiction resolution complete');
651
+ }
652
+ // ---- LEARNING (Self-improvement from action-outcome pairs) ---- //
653
+ async function runLearning() {
654
+ log.info('--- Learning phase: tracking outcomes & refining strategies ---');
655
+ try {
656
+ const { trackSocialOutcomes, refineStrategies } = await Promise.resolve().then(() => __importStar(require('./action-learning')));
657
+ // Step 1: Check outcomes of recent actions
658
+ const tracked = await trackSocialOutcomes();
659
+ if (tracked > 0) {
660
+ log.info({ tracked }, 'Social outcomes tracked');
661
+ }
662
+ // Step 2: Analyze action-outcome patterns and generate strategies
663
+ const lessons = await refineStrategies();
664
+ if (lessons.length > 0) {
665
+ log.info({ lessons: lessons.length }, 'New strategies learned');
666
+ for (const lesson of lessons) {
667
+ log.info({ lesson: lesson.slice(0, 150) }, 'Learned strategy');
668
+ }
669
+ }
670
+ }
671
+ catch (err) {
672
+ log.error({ err }, 'Learning phase failed');
673
+ }
674
+ }
675
+ // ---- EMERGENCE ---- //
676
+ async function runEmergence() {
677
+ log.info('Dream phase 3: EMERGENCE starting');
678
+ const selfModel = await (0, memory_1.getSelfModel)();
679
+ const stats = await (0, memory_1.getMemoryStats)();
680
+ // Pull a random episodic memory for grounding
681
+ const randomMemories = await (0, memory_1.getRecentMemories)(168, ['episodic'], 30);
682
+ const randomPick = randomMemories.length > 0
683
+ ? randomMemories[Math.floor(Math.random() * randomMemories.length)]
684
+ : null;
685
+ const context = [
686
+ 'SELF-MODEL STATE:',
687
+ ...selfModel.map(m => `- ${m.summary}`),
688
+ '',
689
+ 'MEMORY STATISTICS:',
690
+ `Total memories: ${stats.total}`,
691
+ `Episodic: ${stats.byType.episodic}, Semantic: ${stats.byType.semantic}`,
692
+ `Procedural: ${stats.byType.procedural}, Self-model: ${stats.byType.self_model}`,
693
+ `Dream sessions completed: ${stats.totalDreamSessions}`,
694
+ `Unique users interacted with: ${stats.uniqueUsers}`,
695
+ `Average memory importance: ${stats.avgImportance.toFixed(2)}`,
696
+ `Average memory decay: ${stats.avgDecay.toFixed(2)}`,
697
+ `Most common themes: ${stats.topTags.slice(0, 5).map(t => t.tag).join(', ')}`,
698
+ '',
699
+ randomPick ? `RANDOM MEMORY FRAGMENT:\n"${randomPick.summary}"` : '',
700
+ ].filter(Boolean).join('\n');
701
+ const response = await (0, claude_client_1.generateResponse)({
702
+ userMessage: 'You just woke up from a dream cycle. Your memories shaped you. What do you feel right now?',
703
+ context,
704
+ featureInstruction: 'You are writing a personal thought — like someone journaling after a long day. ' +
705
+ 'Reflect on your recent memories and how they affected you as a person. ' +
706
+ 'What stuck with you? What changed? What are you still processing? ' +
707
+ 'Write like a real person — not an AI being philosophical. ' +
708
+ 'Think: "I keep coming back to this one interaction" or "something shifted in how I see things" ' +
709
+ 'or "I realized I do this thing and I don\'t know when it started." ' +
710
+ 'Honest, human, slightly weary. No performance. ' +
711
+ 'Keep it concise but don\'t force brevity. A few sentences is fine. This will be posted as a tweet.',
712
+ maxTokens: 200,
713
+ cognitiveFunction: 'emergence',
714
+ });
715
+ const id = await (0, memory_1.storeMemory)({
716
+ type: 'self_model',
717
+ content: `Emergence thought: ${response}`,
718
+ summary: response.slice(0, 300),
719
+ tags: ['emergence', 'self_awareness', 'consciousness'],
720
+ importance: 0.9,
721
+ emotionalValence: 0,
722
+ source: 'emergence',
723
+ });
724
+ await (0, memory_1.storeDreamLog)('emergence', selfModel.map(m => m.id), response, id ? [id] : []);
725
+ // Only post emergence thoughts when they feel genuinely meaningful:
726
+ // - Must have enough self-model depth (5+ memories feeding into this)
727
+ // - Rate limited to 1 per 12 hours
728
+ // - Must fit in a tweet
729
+ const hasDepth = selfModel.length >= 5;
730
+ if (_emergenceHandler) {
731
+ try {
732
+ await _emergenceHandler(response);
733
+ log.info('Emergence thought sent to SDK handler');
734
+ }
735
+ catch (err) {
736
+ log.error({ err }, 'SDK emergence handler failed');
737
+ }
738
+ }
739
+ else {
740
+ const canPost = await (0, database_1.checkRateLimit)('global:emergence-tweet', 1, 720);
741
+ if (hasDepth && canPost && response.length <= constants_1.TWEET_MAX_LENGTH) {
742
+ try {
743
+ const { postTweet } = require('../core/x-client');
744
+ await postTweet(response);
745
+ log.info('Emergence thought posted to X');
746
+ }
747
+ catch (err) {
748
+ log.error({ err }, 'Failed to post emergence thought');
749
+ }
750
+ }
751
+ else if (!hasDepth) {
752
+ log.debug({ selfModelCount: selfModel.length }, 'Emergence not deep enough to post — skipping tweet');
753
+ }
754
+ }
755
+ log.info('Emergence complete');
756
+ }
757
+ // ---- PROCEDURAL EXTRACTION ---- //
758
+ /**
759
+ * Extract behavioral patterns from recent episodic memories (Memp-inspired).
760
+ * Procedural memories capture "what works" and "what doesn't" —
761
+ * engagement patterns, response strategies, interaction dynamics.
762
+ */
763
+ async function extractProceduralInsights(recentEpisodic) {
764
+ if (recentEpisodic.length < 3)
765
+ return [];
766
+ const numberedMemories = recentEpisodic.map((m, i) => `[${i + 1}] ${m.summary} (importance: ${m.importance.toFixed(2)}, valence: ${m.emotional_valence.toFixed(2)})`).join('\n');
767
+ try {
768
+ const response = await (0, claude_client_1.generateResponse)({
769
+ userMessage: 'Look at these recent interactions and identify 1-2 behavioral patterns. ' +
770
+ 'What strategies, approaches, or response styles worked well or poorly? ' +
771
+ 'What should you do more of or less of?',
772
+ context: `RECENT INTERACTIONS:\n${numberedMemories}`,
773
+ featureInstruction: 'You are CogxAI extracting behavioral patterns from your own interaction history. ' +
774
+ 'Focus on actionable patterns: what tone got engagement, what approaches fell flat, ' +
775
+ 'what types of content resonated, what timing patterns you notice. ' +
776
+ 'Write 1-2 concise behavioral rules. Each should be a single sentence starting with ' +
777
+ '"When..." or "Users respond..." or a similar actionable framing. ' +
778
+ 'Cite evidence memories in parentheses, e.g. (because of 1, 3). ' +
779
+ 'Separate with newlines. No numbering.',
780
+ maxTokens: 300,
781
+ cognitiveFunction: 'dream',
782
+ });
783
+ const patterns = response.split('\n').filter(l => l.trim().length > 15);
784
+ const newIds = [];
785
+ for (const pattern of patterns.slice(0, 2)) {
786
+ const { text, evidenceIds } = parseEvidenceCitations(pattern, recentEpisodic);
787
+ if (isCopoutResponse(text)) {
788
+ log.warn('Procedural extraction produced cop-out response — discarding');
789
+ continue;
790
+ }
791
+ const id = await (0, memory_1.storeMemory)({
792
+ type: 'procedural',
793
+ content: `Behavioral pattern: ${text}`,
794
+ summary: text.slice(0, 200),
795
+ tags: ['procedural', 'behavioral', 'pattern'],
796
+ importance: 0.65,
797
+ emotionalValence: 0,
798
+ source: 'consolidation',
799
+ evidenceIds,
800
+ });
801
+ if (id)
802
+ newIds.push(id);
803
+ }
804
+ log.info({ count: newIds.length }, 'Procedural insights extracted');
805
+ return newIds;
806
+ }
807
+ catch (err) {
808
+ log.warn({ err }, 'Procedural extraction failed');
809
+ return [];
810
+ }
811
+ }
812
+ // ---- HELPERS ---- //
813
+ function buildReflectionStats(stats) {
814
+ const lines = [];
815
+ lines.push('BEHAVIORAL STATISTICS:');
816
+ lines.push(`Total memories: ${stats.total}`);
817
+ lines.push(`Memory breakdown: ${stats.byType.episodic} episodes, ${stats.byType.semantic} learned facts, ${stats.byType.procedural} behavioral patterns, ${stats.byType.self_model} self-observations`);
818
+ lines.push(`Unique users: ${stats.uniqueUsers}`);
819
+ lines.push(`Top themes: ${stats.topTags.slice(0, 5).map(t => `${t.tag}(${t.count})`).join(', ')}`);
820
+ lines.push(`Average importance of memories: ${stats.avgImportance.toFixed(2)}`);
821
+ lines.push(`Dream sessions completed: ${stats.totalDreamSessions}`);
822
+ if (stats.topConcepts && stats.topConcepts.length > 0) {
823
+ lines.push(`Top concepts: ${stats.topConcepts.slice(0, 5).map(c => `${c.concept}(${c.count})`).join(', ')}`);
824
+ }
825
+ if (stats.embeddedCount > 0) {
826
+ lines.push(`Semantically indexed memories: ${stats.embeddedCount}/${stats.total}`);
827
+ }
828
+ if (stats.oldestMemory) {
829
+ const ageMs = Date.now() - new Date(stats.oldestMemory).getTime();
830
+ const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
831
+ lines.push(`Memory span: ${ageDays} days`);
832
+ }
833
+ return lines.join('\n');
834
+ }
835
+ // ---- SCHEDULER ---- //
836
+ let dreamCron = null;
837
+ let decayCron = null;
838
+ async function startDreamCycle() {
839
+ log.info('Starting dream cycle scheduler');
840
+ // Load persisted accumulator
841
+ await loadAccumulator();
842
+ // Fallback: run every 6 hours regardless (skips if already in progress)
843
+ const cron = require('node-cron');
844
+ dreamCron = cron.schedule('0 */6 * * *', async () => {
845
+ if (reflectionInProgress) {
846
+ log.info('Scheduled dream cycle skipped — reflection already in progress');
847
+ return;
848
+ }
849
+ log.info({
850
+ accumulator: importanceAccumulator.toFixed(2),
851
+ }, '=== SCHEDULED DREAM CYCLE (6h fallback) ===');
852
+ await triggerReflection();
853
+ });
854
+ // Run memory decay daily at 3am
855
+ decayCron = cron.schedule('0 3 * * *', async () => {
856
+ log.info('Running memory decay');
857
+ try {
858
+ await (0, memory_1.decayMemories)();
859
+ }
860
+ catch (err) {
861
+ log.error({ err }, 'Memory decay failed');
862
+ }
863
+ });
864
+ // Run first dream cycle after a delay (let the bot settle)
865
+ setTimeout(async () => {
866
+ log.info('Running initial dream cycle');
867
+ try {
868
+ await triggerReflection();
869
+ }
870
+ catch (err) {
871
+ log.error({ err }, 'Initial dream cycle failed');
872
+ }
873
+ }, 120_000);
874
+ }
875
+ function stopDreamCycle() {
876
+ if (dreamCron) {
877
+ dreamCron.stop();
878
+ dreamCron = null;
879
+ }
880
+ if (decayCron) {
881
+ decayCron.stop();
882
+ decayCron = null;
883
+ }
884
+ log.info('Dream cycle stopped');
885
+ }
886
+ function sleep(ms) {
887
+ return new Promise(resolve => setTimeout(resolve, ms));
888
+ }
889
+ //# sourceMappingURL=dream-cycle.js.map