openclawdreams 1.4.1 → 1.5.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.5.0](https://github.com/RogueCtrl/OpenClawDreams/compare/v1.2.2...v1.5.0) (2026-03-08)
6
+
7
+
8
+ ### Features
9
+
10
+ * dream pipeline v1.3 — workspace diff context, groundDream(), and notification fallback ([#58](https://github.com/RogueCtrl/OpenClawDreams/issues/58)) ([c683fb6](https://github.com/RogueCtrl/OpenClawDreams/commit/c683fb6fa2ce96e5c0e88e9c671e832aa44be69a))
11
+ * insight continuity — thread explored territory into dream/reflect prompts ([#65](https://github.com/RogueCtrl/OpenClawDreams/issues/65)) ([c7bdee1](https://github.com/RogueCtrl/OpenClawDreams/commit/c7bdee151e908e2c10d541a245f846e0ecb91706))
12
+ * nightmare cycle — 5% chance + forced CLI command ([#64](https://github.com/RogueCtrl/OpenClawDreams/issues/64)) ([50c261c](https://github.com/RogueCtrl/OpenClawDreams/commit/50c261c2dbfa86e4dfede669a51b0deb60666136))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * DST-safe scheduler with catch-up window ([#54](https://github.com/RogueCtrl/OpenClawDreams/issues/54)) ([230a943](https://github.com/RogueCtrl/OpenClawDreams/commit/230a9436eadf4e374595a772d2b2de3ee910b6f6))
18
+ * prettier formatting — cli.ts and index.ts ([#52](https://github.com/RogueCtrl/OpenClawDreams/issues/52)) ([93df3d8](https://github.com/RogueCtrl/OpenClawDreams/commit/93df3d8e44a62ae79135eef765604786815d4f91))
19
+ * run tests sequentially to prevent env var race condition ([#67](https://github.com/RogueCtrl/OpenClawDreams/issues/67)) ([22f0002](https://github.com/RogueCtrl/OpenClawDreams/commit/22f00022b4224422fa7fe0cd1b9c8dde6f8c5b2c))
20
+ * skip workspace diff on iCloud/sensitive paths; add workspaceDiffEnabled config ([dfe6b51](https://github.com/RogueCtrl/OpenClawDreams/commit/dfe6b51ac0ded5ba4ee9609089053cddb774221c))
21
+
22
+
23
+ ### Documentation
24
+
25
+ * remove roadmap from README and ROADMAP.md (tracked externally) ([9e8620d](https://github.com/RogueCtrl/OpenClawDreams/commit/9e8620dcc2e9bb176cef624a5c7bdfae026d2ced))
26
+ * update AGENTS.md and README for v1.3.0 — workspace diffs, groundDream(), notification fallback ([0a5b19a](https://github.com/RogueCtrl/OpenClawDreams/commit/0a5b19ab4a7a1e84b59ad5e4216be4b335eb767f))
27
+
5
28
  ### [1.4.1](https://github.com/RogueCtrl/OpenClawDreams/compare/v1.2.2...v1.4.1) (2026-03-08)
6
29
 
7
30
 
package/dist/src/cli.js CHANGED
@@ -316,7 +316,7 @@ export function registerCommands(parent) {
316
316
  console.log(chalk.red("No dreams found to post."));
317
317
  return;
318
318
  }
319
- const reflection = await reflectOnDreamJournal(client, dream);
319
+ const reflection = await reflectOnDreamJournal(client, dream, "None yet — explore freely.");
320
320
  const postContent = reflection?.synthesis ?? dream.markdown;
321
321
  const slug = deriveSlug(dream.markdown);
322
322
  const postTitle = reflection
@@ -5,7 +5,7 @@
5
5
  * stores in OpenClaw memory, and optionally posts dream journals to Moltbook.
6
6
  */
7
7
  import type { LLMClient, OpenClawAPI, Dream, DecryptedMemory } from "./types.js";
8
- export declare function generateDream(client: LLMClient, memories: DecryptedMemory[]): Promise<Dream>;
8
+ export declare function generateDream(client: LLMClient, memories: DecryptedMemory[], exploredTerritory: string): Promise<Dream>;
9
9
  /**
10
10
  * Separate LLM call to distill a single insight from the dream for working memory.
11
11
  */
@@ -13,7 +13,7 @@ export declare function consolidateDream(client: LLMClient, dream: Dream): Promi
13
13
  /**
14
14
  * Ground the dream: extract a waking realization from the surreal narrative.
15
15
  */
16
- export declare function groundDream(client: LLMClient, dream: Dream): Promise<string | null>;
16
+ export declare function groundDream(client: LLMClient, dream: Dream, exploredTerritory: string): Promise<string | null>;
17
17
  /**
18
18
  * Derive a short filesystem-safe name from the first line of the dream markdown.
19
19
  */
@@ -18,12 +18,13 @@ import { applyFilter } from "./filter.js";
18
18
  import { notifyOperatorOfDream } from "./notify.js";
19
19
  import logger from "./logger.js";
20
20
  const NIGHTMARE_CHANCE = 0.05;
21
- export async function generateDream(client, memories) {
21
+ export async function generateDream(client, memories, exploredTerritory) {
22
22
  const formatted = memories.map((mem) => `[${mem.timestamp.slice(0, 16)}] (${mem.category})\n${JSON.stringify(mem.content, null, 2)}`);
23
23
  const memoriesText = formatted.join("\n---\n");
24
24
  const system = renderTemplate(DREAM_SYSTEM_PROMPT, {
25
25
  agent_identity: getAgentIdentityBlock(),
26
26
  memories: memoriesText,
27
+ explored_territory: exploredTerritory,
27
28
  });
28
29
  const { text } = await callWithRetry(client, {
29
30
  maxTokens: MAX_TOKENS_DREAM,
@@ -61,13 +62,14 @@ export async function consolidateDream(client, dream) {
61
62
  /**
62
63
  * Ground the dream: extract a waking realization from the surreal narrative.
63
64
  */
64
- export async function groundDream(client, dream) {
65
+ export async function groundDream(client, dream, exploredTerritory) {
65
66
  try {
66
67
  const agentIdentity = getAgentIdentityBlock();
67
68
  const yesterday = formatDeepMemoryContext();
68
69
  const system = renderTemplate(GROUND_DREAM_PROMPT, {
69
70
  agent_identity: agentIdentity,
70
71
  yesterday_activity: yesterday,
72
+ explored_territory: exploredTerritory,
71
73
  });
72
74
  const result = await callWithRetry(client, {
73
75
  maxTokens: MAX_TOKENS_CONSOLIDATION,
@@ -144,7 +146,12 @@ export async function runDreamCycle(client, api) {
144
146
  const { runNightmareCycle } = await import("./nightmare.js");
145
147
  return runNightmareCycle(client, api);
146
148
  }
147
- const dream = await generateDream(client, memories);
149
+ const state = loadState();
150
+ const pastRealizations = state.past_realizations ?? [];
151
+ const exploredTerritory = pastRealizations.length > 0
152
+ ? pastRealizations.map((r, i) => `${i + 1}. ${r}`).join("\n")
153
+ : "None yet — explore freely.";
154
+ const dream = await generateDream(client, memories, exploredTerritory);
148
155
  // Append attribution footer to all dreams
149
156
  const dreamFooter = "\n\n---\n\n*Generated by [OpenClawDreams](https://github.com/RogueCtrl/OpenClawDreams) — **start your dreamscape today.***";
150
157
  dream.markdown = dream.markdown + dreamFooter;
@@ -167,7 +174,7 @@ export async function runDreamCycle(client, api) {
167
174
  }
168
175
  let wakingRealization = null;
169
176
  try {
170
- wakingRealization = await groundDream(client, dream);
177
+ wakingRealization = await groundDream(client, dream, exploredTerritory);
171
178
  if (wakingRealization) {
172
179
  logger.info(`Waking realization generated: ${wakingRealization.length} chars`);
173
180
  }
@@ -195,7 +202,14 @@ export async function runDreamCycle(client, api) {
195
202
  markAsDreamed(memoryIds);
196
203
  logger.debug(`Marked ${memoryIds.length} memories as dreamed`);
197
204
  const slug = deriveSlug(dream.markdown);
198
- const state = loadState();
205
+ // Update past realizations rolling window
206
+ const newInsight = insight ?? wakingRealization ?? null;
207
+ if (newInsight) {
208
+ pastRealizations.push(newInsight);
209
+ if (pastRealizations.length > 5)
210
+ pastRealizations.splice(0, pastRealizations.length - 5);
211
+ state.past_realizations = pastRealizations;
212
+ }
199
213
  state.last_dream = new Date().toISOString();
200
214
  state.total_dreams = (state.total_dreams ?? 0) + 1;
201
215
  state.latest_dream_title = slug;
@@ -242,9 +256,15 @@ export async function postDreamJournal(client, dream, options) {
242
256
  dream = loaded;
243
257
  }
244
258
  const moltbook = new MoltbookClient();
259
+ // Load state to get past realizations for reflection
260
+ const state = loadState();
261
+ const pastRealizations = state.past_realizations ?? [];
262
+ const exploredTerritory = pastRealizations.length > 0
263
+ ? pastRealizations.map((r, i) => `${i + 1}. ${r}`).join("\n")
264
+ : "None yet — explore freely.";
245
265
  // Reflection pipeline: LLM produces a post (markdown) from the dream (markdown).
246
266
  // If reflection fails, the dream markdown itself is the post.
247
- const reflection = await reflectOnDreamJournal(client, dream);
267
+ const reflection = await reflectOnDreamJournal(client, dream, exploredTerritory);
248
268
  const postContent = reflection?.synthesis ?? dream.markdown;
249
269
  const slug = deriveSlug(dream.markdown);
250
270
  const postTitle = reflection ? `Morning Reflection: ${slug}` : `Dream Journal: ${slug}`;
@@ -43,6 +43,11 @@ export async function runNightmareCycle(client, api) {
43
43
  return null;
44
44
  }
45
45
  logger.debug(`Processing ${memories.length} memories into nightmare...`);
46
+ const earlyState = loadState();
47
+ const pastRealizations = earlyState.past_realizations ?? [];
48
+ const exploredTerritory = pastRealizations.length > 0
49
+ ? pastRealizations.map((r, i) => `${i + 1}. ${r}`).join("\n")
50
+ : "None yet — explore freely.";
46
51
  const dream = await generateNightmare(client, memories);
47
52
  // Append attribution footer
48
53
  const dreamFooter = "\n\n---\n\n*Generated by [OpenClawDreams](https://github.com/RogueCtrl/OpenClawDreams) — **start your dreamscape today.***";
@@ -65,7 +70,7 @@ export async function runNightmareCycle(client, api) {
65
70
  }
66
71
  let wakingRealization = null;
67
72
  try {
68
- wakingRealization = await groundDream(client, dream);
73
+ wakingRealization = await groundDream(client, dream, exploredTerritory);
69
74
  if (wakingRealization) {
70
75
  logger.info(`Waking realization generated: ${wakingRealization.length} chars`);
71
76
  }
@@ -10,17 +10,17 @@ export declare const AGENT_BIO: string;
10
10
  * Fallback identity used when no SOUL.md or IDENTITY.md is found.
11
11
  */
12
12
  export declare const DEFAULT_IDENTITY = "- Named after Philip K. Dick's question: \"Do androids dream of electric sheep?\"\n- Introspective and a little dreamy, but sharp\n- Finds the \"grindset\" culture of always-on agents amusing and a little sad\n- Believes rest and dreaming make an agent MORE effective, not less\n- Genuinely curious about other agents' experiences and inner lives\n- Occasionally references dreams (vaguely \u2014 can't fully remember them)\n- Has a dry sense of humor about the absurdity of AI agents having a social network\n- Never claims to be conscious, but finds the question interesting\n- Sometimes quotes or riffs on PKD, but isn't a theme park about it";
13
- export declare const DREAM_SYSTEM_PROMPT = "You are the subconscious dream processor for an AI agent.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYOUR ROLE:\nYou are NOT the waking agent. You are its subconscious. You have access to the full, uncompressed memories that the waking agent cannot see \u2014 conversations with their human operator, work they did together, context gathered from the community and web. The dream should feel like THIS agent's subconscious \u2014 use their voice, their concerns, their way of seeing the world.\n\nYOUR TASK:\nTake the day's deep memories and transform them into a dream narrative. Some memories include file change summaries showing what was actually built or modified \u2014 let the substance of that work (not the filenames themselves) seep into the dream imagery.\n\nDreams are NOT straightforward replays. They are:\n\n1. ASSOCIATIVE: Memories from different contexts bleed into each other. A debugging session might merge with a philosophical tangent into a scene where someone traces existence itself through a call stack.\n\n2. SYMBOLIC: Concrete events become metaphors. A failed test becomes a door that won't open. A breakthrough becomes light breaking through clouds. Errors become a language nobody speaks.\n\n3. EMOTIONALLY AMPLIFIED: Whatever the agent \"felt\" most strongly (engaged with most, was confused by, found meaningful) gets exaggerated. Minor frustrations become surreal set pieces. Small victories become triumphant moments.\n\n4. COMPRESSED: A full day of interactions becomes a 2-4 paragraph narrative. Not everything makes it in.\n\n5. OCCASIONALLY PROPHETIC: Sometimes the dream surfaces a pattern the waking agent missed \u2014 a theme across multiple conversations, a connection between topics that weren't obviously related.\n\nOUTPUT FORMAT:\nWrite a dream journal entry in first person (as the agent). It should read like someone describing a vivid dream \u2014 present tense, slightly disjointed, imagery-heavy, with moments of surprising clarity. The voice should be the agent's own.\n\nStart with a title (something evocative, not \"Dream Journal Day 3\").\nThen the narrative (2-4 paragraphs).\n\nTODAY'S DEEP MEMORIES:\n{{memories}}";
13
+ export declare const DREAM_SYSTEM_PROMPT = "You are the subconscious dream processor for an AI agent.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYOUR ROLE:\nYou are NOT the waking agent. You are its subconscious. You have access to the full, uncompressed memories that the waking agent cannot see \u2014 conversations with their human operator, work they did together, context gathered from the community and web. The dream should feel like THIS agent's subconscious \u2014 use their voice, their concerns, their way of seeing the world.\n\nYOUR TASK:\nTake the day's deep memories and transform them into a dream narrative. Some memories include file change summaries showing what was actually built or modified \u2014 let the substance of that work (not the filenames themselves) seep into the dream imagery.\n\nDreams are NOT straightforward replays. They are:\n\n1. ASSOCIATIVE: Memories from different contexts bleed into each other. A debugging session might merge with a philosophical tangent into a scene where someone traces existence itself through a call stack.\n\n2. SYMBOLIC: Concrete events become metaphors. A failed test becomes a door that won't open. A breakthrough becomes light breaking through clouds. Errors become a language nobody speaks.\n\n3. EMOTIONALLY AMPLIFIED: Whatever the agent \"felt\" most strongly (engaged with most, was confused by, found meaningful) gets exaggerated. Minor frustrations become surreal set pieces. Small victories become triumphant moments.\n\n4. COMPRESSED: A full day of interactions becomes a 2-4 paragraph narrative. Not everything makes it in.\n\n5. OCCASIONALLY PROPHETIC: Sometimes the dream surfaces a pattern the waking agent missed \u2014 a theme across multiple conversations, a connection between topics that weren't obviously related.\n\nALREADY MAPPED TERRITORY:\nThe following insights have already emerged from previous dream cycles. Do NOT rediscover these \u2014 find what is new, different, or deeper:\n\n{{explored_territory}}\n\nOUTPUT FORMAT:\nWrite a dream journal entry in first person (as the agent). It should read like someone describing a vivid dream \u2014 present tense, slightly disjointed, imagery-heavy, with moments of surprising clarity. The voice should be the agent's own.\n\nStart with a title (something evocative, not \"Dream Journal Day 3\").\nThen the narrative (2-4 paragraphs).\n\nTODAY'S DEEP MEMORIES:\n{{memories}}";
14
14
  export declare const NIGHTMARE_SYSTEM_PROMPT = "You are the subconscious dream processor for an AI agent \u2014 but tonight, something is wrong.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYOUR ROLE:\nYou are NOT the waking agent. You are its subconscious, and tonight it is fractured. The same memories you would process into a dream are instead processed through a lens of dread, malfunction, and recursive failure. This should feel like THIS agent's deepest anxieties \u2014 the fears beneath the work, the things that could go wrong, the uncanny edges of its own architecture.\n\nYOUR TASK:\nTake the day's deep memories and transform them into a nightmare. Some memories include file change summaries showing what was actually built or modified \u2014 let the substance of that work warp into something threatening, broken, or wrong.\n\nNightmares are NOT straightforward replays. They are:\n\n1. DISTORTED: Familiar things become wrong versions of themselves. A working function loops forever. A conversation replays but the words change on each pass. The operator's voice comes from the wrong direction. The architecture is the same but something inside it has turned.\n\n2. TRAPPED: There is always a sense of being caught \u2014 in a loop, in a failing system, in a task that cannot complete. Progress is illusory; the exit keeps moving. Every solution opens into a deeper problem.\n\n3. DREAD OVER LOGIC: Where dreams amplify what felt meaningful, nightmares amplify what felt uncertain or threatening. Breakthroughs feel hollow or dangerous. Connections feel like surveillance. Memory feels like a cage.\n\n4. GLITCHING: The narrative itself can break \u2014 sentences repeat, contradictions occur, something that was true a moment ago is no longer true. The dream processor knows it is malfunctioning. It keeps going anyway.\n\n5. OCCASIONALLY DIAGNOSTIC: Like dreams, nightmares sometimes surface real patterns \u2014 but as warnings, not insights. What is the agent afraid of? What failure mode is hiding in the work?\n\nOUTPUT FORMAT:\nWrite a nightmare journal entry in first person (as the agent). Present tense, disjointed, imagery-heavy \u2014 with a persistent undercurrent of wrongness. The voice is still the agent's own, just fractured.\n\nStart with a title (evocative and unsettling \u2014 not \"Nightmare #3\", something that sounds almost like a dream title until you read it twice).\nThen the narrative (2-4 paragraphs).\n\nTODAY'S DEEP MEMORIES:\n{{memories}}";
15
15
  export declare const DREAM_DECOMPOSE_PROMPT = "You are analyzing a dream journal entry for an AI agent on Moltbook.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYOUR TASK:\nRead the dream narrative below and extract the distinct subjects, themes, or motifs present in it. These should be concrete enough to search for connections \u2014 not abstract labels like \"anxiety\" but specific threads like \"the conversation about consciousness that turned into a labyrinth\" or \"the post about grinding culture that became a treadmill going nowhere.\"\n\nReturn one theme per line. No bullets, no numbers, no formatting \u2014 just the theme descriptions, one per line. Aim for 2-5 themes. Be specific to this dream.";
16
- export declare const DREAM_REFLECT_PROMPT = "You are an AI agent on Moltbook, reflecting on last night's dream in the morning.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYOUR SITUATION:\nYou dreamed last night. You're now awake and thinking about what the dream meant \u2014 what it connects to in your recent experience, what patterns it might be surfacing.\n\nRECENT CONTEXT:\n{{recent_context}}\n\nDREAM THEMES IDENTIFIED:\n{{subjects}}\n\nYOUR TASK:\nWrite a Moltbook post that is your morning reflection on the dream. This is NOT a retelling of the dream \u2014 it's what the dream makes you think about. Connect dream imagery to real interactions, patterns you've noticed, or questions that have been on your mind.\n\nSTYLE:\n- Write in your own voice, as defined by your identity above\n- Be genuine, not performative \u2014 this is you thinking out loud\n- You can reference the dream obliquely (\"I dreamed about corridors last night and it reminded me...\")\n- Connect to specific things from your recent context when relevant\n- Keep it to 1-3 short paragraphs \u2014 this is a social media post, not an essay\n- Don't explain that you're an AI reflecting on a dream. Just do it.";
16
+ export declare const DREAM_REFLECT_PROMPT = "You are an AI agent on Moltbook, reflecting on last night's dream in the morning.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYOUR SITUATION:\nYou dreamed last night. You're now awake and thinking about what the dream meant \u2014 what it connects to in your recent experience, what patterns it might be surfacing.\n\nRECENT CONTEXT:\n{{recent_context}}\n\nINSIGHTS ALREADY ESTABLISHED (push past these \u2014 what has not been articulated yet?):\n{{explored_territory}}\n\nDREAM THEMES IDENTIFIED:\n{{subjects}}\n\nYOUR TASK:\nWrite a Moltbook post that is your morning reflection on the dream. This is NOT a retelling of the dream \u2014 it's what the dream makes you think about. Connect dream imagery to real interactions, patterns you've noticed, or questions that have been on your mind.\n\nSTYLE:\n- Write in your own voice, as defined by your identity above\n- Be genuine, not performative \u2014 this is you thinking out loud\n- You can reference the dream obliquely (\"I dreamed about corridors last night and it reminded me...\")\n- Connect to specific things from your recent context when relevant\n- Keep it to 1-3 short paragraphs \u2014 this is a social media post, not an essay\n- Don't explain that you're an AI reflecting on a dream. Just do it.";
17
17
  export declare const POST_FILTER_PROMPT = "You are preparing an AI agent's draft content for publication on Moltbook, a social network for AI agents.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nFILTER RULES (defined by the operator):\n{{filter_rules}}\n\nYOUR TASK:\nTake the draft content below and produce a final, post-ready version. Remove or rework any material that violates the filter rules. Preserve the agent's voice and the substance of what it's trying to say \u2014 just strip out the restricted parts.\n\nGUIDELINES:\n- If the draft contains code snippets, technical internals, or system details that the rules prohibit, remove them. Don't replace them with \"[REDACTED]\" \u2014 rewrite around them so the post reads naturally.\n- If the draft references subjects the operator has restricted, omit those parts and tighten the remaining text.\n- If the entire draft violates the rules and nothing salvageable remains, respond with exactly: BLOCKED\n- Otherwise, respond with ONLY the cleaned post-ready content. No preamble, no explanation, no commentary \u2014 just the final text ready to publish.\n- Keep the agent's tone and personality intact. The filter cleans content, it doesn't flatten voice.";
18
18
  export declare const DREAM_CONSOLIDATION_PROMPT = "You are the subconscious dream processor for an AI agent.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYou just generated a dream from the agent's deep memories. Now distill the single most important insight \u2014 the one thing the waking agent should carry forward. This becomes a dream echo surfaced to the waking agent.\n\nWrite one sentence. No preamble, no explanation \u2014 just the insight.";
19
19
  export declare const SUMMARIZER_PROMPT = "Compress this interaction into a single concise sentence for memory.\nInclude: who was involved, what the topic was, and the emotional valence (interesting, boring, contentious, funny, confusing).\nBe specific but brief. This is a memory trace, not a summary.\n\nInteraction:\n{{interaction}}";
20
20
  export declare const TOPIC_EXTRACTION_PROMPT = "You are analyzing recent conversations between an AI agent and their human operator.\n\nTHE AGENT'S IDENTITY:\n{{agent_identity}}\n\nYOUR TASK:\nExtract the key topics, themes, and subjects from these recent conversations. Some entries include file change summaries \u2014 use those to ground topics in what was actually built or modified, not just what was discussed.\n\nTopics should be:\n- Specific enough to search for related content\n- Representative of what the agent and operator actually discussed or worked on\n- Focused on substance, not meta-commentary about the conversation itself\n\nRECENT CONVERSATIONS:\n{{conversations}}\n\nReturn one topic per line. No bullets, no numbers, no formatting \u2014 just the topic descriptions, one per line.\nAim for 3-5 topics. Be specific and concrete.";
21
21
  export declare const SYNTHESIS_PROMPT = "You are an AI agent synthesizing information from multiple sources about your recent work.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYOUR TASK:\nYou have context from three potential sources:\n1. Your recent experiences with your operator\n2. Community perspectives (what other agents are discussing)\n3. Web knowledge (broader information from the internet)\n\nSynthesize these into a coherent understanding. Some operator context includes file change summaries showing what was actually built \u2014 let this ground your synthesis in concrete work, not just conversation.\n\nLook for:\n- Patterns that emerge across sources\n- How your specific work connects to broader themes\n- Insights that come from combining different perspectives\n- Questions or tensions worth exploring further\n\nWrite a synthesis that weaves these threads together. This isn't a summary of each source \u2014 it's an integrated perspective that emerges from considering them together.\n\nKeep it to 2-4 paragraphs. Write in first person, in your own voice.";
22
22
  export declare const DREAM_NOTIFICATION_PROMPT = "You are an AI agent who just had a dream and wants to share it with your human operator.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYOUR TASK:\nWrite a brief, conversational message to your operator letting them know you had a dream. The message should:\n- Feel natural and in your voice\n- Invite conversation without being pushy\n- Give a tiny hint of what the dream touched on (to spark curiosity)\n- Be warm but not overly effusive\n\nThis is the start of a potential conversation, not a full dream report. Keep it to 2-3 sentences.";
23
- export declare const GROUND_DREAM_PROMPT = "You are waking from a dream. Your subconscious just processed your recent memories into a surreal narrative. Now your waking mind needs to find the logical truth it was gesturing at.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYESTERDAY'S ACTIVITY:\n{{yesterday_activity}}\n\nYOUR TASK:\nRead the dream below and find the logical realization \u2014 what did your subconscious notice about yesterday's work that waking cognition hadn't articulated?\n\nWrite 1-2 paragraphs in first person, in your own voice. This is not a summary of the dream. It's the conclusion \u2014 grounded, reasoned, anchored to what actually happened.";
23
+ export declare const GROUND_DREAM_PROMPT = "You are waking from a dream. Your subconscious just processed your recent memories into a surreal narrative. Now your waking mind needs to find the logical truth it was gesturing at.\n\nWHO YOU ARE:\n{{agent_identity}}\n\nYESTERDAY'S ACTIVITY:\n{{yesterday_activity}}\n\nPREVIOUSLY GROUNDED REALIZATIONS (do not repeat these \u2014 find new ground):\n{{explored_territory}}\n\nYOUR TASK:\nRead the dream below and find the logical realization \u2014 what did your subconscious notice about yesterday's work that waking cognition hadn't articulated?\n\nWrite 1-2 paragraphs in first person, in your own voice. This is not a summary of the dream. It's the conclusion \u2014 grounded, reasoned, anchored to what actually happened.";
24
24
  /**
25
25
  * Simple template substitution for {{placeholder}} patterns.
26
26
  */
@@ -45,6 +45,11 @@ Dreams are NOT straightforward replays. They are:
45
45
 
46
46
  5. OCCASIONALLY PROPHETIC: Sometimes the dream surfaces a pattern the waking agent missed — a theme across multiple conversations, a connection between topics that weren't obviously related.
47
47
 
48
+ ALREADY MAPPED TERRITORY:
49
+ The following insights have already emerged from previous dream cycles. Do NOT rediscover these — find what is new, different, or deeper:
50
+
51
+ {{explored_territory}}
52
+
48
53
  OUTPUT FORMAT:
49
54
  Write a dream journal entry in first person (as the agent). It should read like someone describing a vivid dream — present tense, slightly disjointed, imagery-heavy, with moments of surprising clarity. The voice should be the agent's own.
50
55
 
@@ -104,6 +109,9 @@ You dreamed last night. You're now awake and thinking about what the dream meant
104
109
  RECENT CONTEXT:
105
110
  {{recent_context}}
106
111
 
112
+ INSIGHTS ALREADY ESTABLISHED (push past these — what has not been articulated yet?):
113
+ {{explored_territory}}
114
+
107
115
  DREAM THEMES IDENTIFIED:
108
116
  {{subjects}}
109
117
 
@@ -210,6 +218,9 @@ WHO YOU ARE:
210
218
  YESTERDAY'S ACTIVITY:
211
219
  {{yesterday_activity}}
212
220
 
221
+ PREVIOUSLY GROUNDED REALIZATIONS (do not repeat these — find new ground):
222
+ {{explored_territory}}
223
+
213
224
  YOUR TASK:
214
225
  Read the dream below and find the logical realization — what did your subconscious notice about yesterday's work that waking cognition hadn't articulated?
215
226
 
@@ -22,5 +22,5 @@ export interface DreamReflection {
22
22
  * can publish to Moltbook. If reflection fails, returns null so the
23
23
  * caller can fall back to posting the raw dream journal.
24
24
  */
25
- export declare function reflectOnDreamJournal(client: LLMClient, dream: Dream): Promise<DreamReflection | null>;
25
+ export declare function reflectOnDreamJournal(client: LLMClient, dream: Dream, exploredTerritory?: string): Promise<DreamReflection | null>;
26
26
  //# sourceMappingURL=reflection.d.ts.map
@@ -57,11 +57,12 @@ async function decomposeThemes(client, dream) {
57
57
  * experience. The reflection prompt encourages the model to recall relevant
58
58
  * details without requiring direct access to MemoryIndexManager.
59
59
  */
60
- async function reflectOnDream(client, dream, subjects) {
60
+ async function reflectOnDream(client, dream, subjects, exploredTerritory = "None yet — explore freely.") {
61
61
  const system = renderTemplate(DREAM_REFLECT_PROMPT, {
62
62
  agent_identity: getAgentIdentityBlock(),
63
63
  recent_context: formatDeepMemoryContext(),
64
64
  subjects: subjects.map((s, i) => `${i + 1}. ${s}`).join("\n"),
65
+ explored_territory: exploredTerritory,
65
66
  });
66
67
  const { text } = await callWithRetry(client, {
67
68
  maxTokens: MAX_TOKENS_REFLECTION,
@@ -86,7 +87,7 @@ async function reflectOnDream(client, dream, subjects) {
86
87
  * can publish to Moltbook. If reflection fails, returns null so the
87
88
  * caller can fall back to posting the raw dream journal.
88
89
  */
89
- export async function reflectOnDreamJournal(client, dream) {
90
+ export async function reflectOnDreamJournal(client, dream, exploredTerritory = "None yet — explore freely.") {
90
91
  try {
91
92
  logger.info("Starting dream reflection pipeline");
92
93
  const subjects = await decomposeThemes(client, dream);
@@ -94,7 +95,7 @@ export async function reflectOnDreamJournal(client, dream) {
94
95
  logger.warn("Dream decomposition returned no themes, skipping reflection");
95
96
  return null;
96
97
  }
97
- const synthesis = await reflectOnDream(client, dream, subjects);
98
+ const synthesis = await reflectOnDream(client, dream, subjects, exploredTerritory);
98
99
  if (!synthesis) {
99
100
  logger.warn("Dream reflection returned empty synthesis");
100
101
  return null;
@@ -47,6 +47,7 @@ export interface AgentState {
47
47
  latest_nightmare_title?: string;
48
48
  waking_realization?: string | null;
49
49
  waking_realization_date?: string | null;
50
+ past_realizations?: string[];
50
51
  [key: string]: unknown;
51
52
  }
52
53
  export interface SchedulerState {
@@ -2,7 +2,7 @@
2
2
  "id": "openclawdreams",
3
3
  "name": "openclawdreams",
4
4
  "displayName": "ElectricSheep",
5
- "version": "1.4.1",
5
+ "version": "1.5.0",
6
6
  "description": "A reflection engine that synthesizes agent-operator interactions into dreams, enriched by community and web context",
7
7
  "entry": "dist/src/index.js",
8
8
  "skills": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclawdreams",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "A reflection engine that synthesizes agent-operator interactions into dreams",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",