openclawdreams 0.7.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/.env.example +14 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/.github/dependabot.yml +17 -0
- package/.github/pull_request_template.md +19 -0
- package/.github/workflows/build.yml +30 -0
- package/.github/workflows/release.yml +110 -0
- package/.prettierignore +4 -0
- package/.prettierrc +7 -0
- package/.versionrc.json +26 -0
- package/AGENTS.md +286 -0
- package/CHANGELOG.md +157 -0
- package/CODE_OF_CONDUCT.md +41 -0
- package/CONTRIBUTING.md +95 -0
- package/LICENSE +21 -0
- package/README.md +363 -0
- package/SECURITY.md +39 -0
- package/bin/electricsheep.ts +5 -0
- package/dist/bin/electricsheep.d.ts +3 -0
- package/dist/bin/electricsheep.d.ts.map +1 -0
- package/dist/bin/electricsheep.js +4 -0
- package/dist/bin/electricsheep.js.map +1 -0
- package/dist/src/budget.d.ts +28 -0
- package/dist/src/budget.d.ts.map +1 -0
- package/dist/src/budget.js +87 -0
- package/dist/src/budget.js.map +1 -0
- package/dist/src/cli.d.ts +19 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +289 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +37 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +70 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/crypto.d.ts +19 -0
- package/dist/src/crypto.d.ts.map +1 -0
- package/dist/src/crypto.js +70 -0
- package/dist/src/crypto.js.map +1 -0
- package/dist/src/dreamer.d.ts +13 -0
- package/dist/src/dreamer.d.ts.map +1 -0
- package/dist/src/dreamer.js +213 -0
- package/dist/src/dreamer.js.map +1 -0
- package/dist/src/filter.d.ts +30 -0
- package/dist/src/filter.d.ts.map +1 -0
- package/dist/src/filter.js +124 -0
- package/dist/src/filter.js.map +1 -0
- package/dist/src/identity.d.ts +29 -0
- package/dist/src/identity.d.ts.map +1 -0
- package/dist/src/identity.js +83 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +293 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm.d.ts +26 -0
- package/dist/src/llm.d.ts.map +1 -0
- package/dist/src/llm.js +40 -0
- package/dist/src/llm.js.map +1 -0
- package/dist/src/logger.d.ts +6 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +32 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/memory.d.ts +41 -0
- package/dist/src/memory.d.ts.map +1 -0
- package/dist/src/memory.js +206 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/moltbook-search.d.ts +23 -0
- package/dist/src/moltbook-search.d.ts.map +1 -0
- package/dist/src/moltbook-search.js +85 -0
- package/dist/src/moltbook-search.js.map +1 -0
- package/dist/src/moltbook.d.ts +34 -0
- package/dist/src/moltbook.d.ts.map +1 -0
- package/dist/src/moltbook.js +165 -0
- package/dist/src/moltbook.js.map +1 -0
- package/dist/src/notify.d.ts +18 -0
- package/dist/src/notify.d.ts.map +1 -0
- package/dist/src/notify.js +98 -0
- package/dist/src/notify.js.map +1 -0
- package/dist/src/persona.d.ts +26 -0
- package/dist/src/persona.d.ts.map +1 -0
- package/dist/src/persona.js +178 -0
- package/dist/src/persona.js.map +1 -0
- package/dist/src/reflection.d.ts +26 -0
- package/dist/src/reflection.d.ts.map +1 -0
- package/dist/src/reflection.js +111 -0
- package/dist/src/reflection.js.map +1 -0
- package/dist/src/state.d.ts +7 -0
- package/dist/src/state.d.ts.map +1 -0
- package/dist/src/state.js +40 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/synthesis.d.ts +29 -0
- package/dist/src/synthesis.d.ts.map +1 -0
- package/dist/src/synthesis.js +125 -0
- package/dist/src/synthesis.js.map +1 -0
- package/dist/src/topics.d.ts +19 -0
- package/dist/src/topics.d.ts.map +1 -0
- package/dist/src/topics.js +83 -0
- package/dist/src/topics.js.map +1 -0
- package/dist/src/types.d.ts +179 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/waking.d.ts +24 -0
- package/dist/src/waking.d.ts.map +1 -0
- package/dist/src/waking.js +152 -0
- package/dist/src/waking.js.map +1 -0
- package/dist/src/web-search.d.ts +23 -0
- package/dist/src/web-search.d.ts.map +1 -0
- package/dist/src/web-search.js +64 -0
- package/dist/src/web-search.js.map +1 -0
- package/dist/test/budget.test.d.ts +2 -0
- package/dist/test/budget.test.d.ts.map +1 -0
- package/dist/test/budget.test.js +258 -0
- package/dist/test/budget.test.js.map +1 -0
- package/dist/test/crypto.test.d.ts +2 -0
- package/dist/test/crypto.test.d.ts.map +1 -0
- package/dist/test/crypto.test.js +93 -0
- package/dist/test/crypto.test.js.map +1 -0
- package/dist/test/dreamer.test.d.ts +2 -0
- package/dist/test/dreamer.test.d.ts.map +1 -0
- package/dist/test/dreamer.test.js +79 -0
- package/dist/test/dreamer.test.js.map +1 -0
- package/dist/test/filter.test.d.ts +2 -0
- package/dist/test/filter.test.d.ts.map +1 -0
- package/dist/test/filter.test.js +92 -0
- package/dist/test/filter.test.js.map +1 -0
- package/dist/test/memory.test.d.ts +2 -0
- package/dist/test/memory.test.d.ts.map +1 -0
- package/dist/test/memory.test.js +138 -0
- package/dist/test/memory.test.js.map +1 -0
- package/dist/test/moltbook.test.d.ts +2 -0
- package/dist/test/moltbook.test.d.ts.map +1 -0
- package/dist/test/moltbook.test.js +164 -0
- package/dist/test/moltbook.test.js.map +1 -0
- package/dist/test/persona.test.d.ts +2 -0
- package/dist/test/persona.test.d.ts.map +1 -0
- package/dist/test/persona.test.js +44 -0
- package/dist/test/persona.test.js.map +1 -0
- package/dist/test/reflection.test.d.ts +2 -0
- package/dist/test/reflection.test.d.ts.map +1 -0
- package/dist/test/reflection.test.js +57 -0
- package/dist/test/reflection.test.js.map +1 -0
- package/dist/test/state.test.d.ts +2 -0
- package/dist/test/state.test.d.ts.map +1 -0
- package/dist/test/state.test.js +50 -0
- package/dist/test/state.test.js.map +1 -0
- package/dist/test/waking.test.d.ts +2 -0
- package/dist/test/waking.test.d.ts.map +1 -0
- package/dist/test/waking.test.js +149 -0
- package/dist/test/waking.test.js.map +1 -0
- package/eslint.config.js +35 -0
- package/openclaw.plugin.json +62 -0
- package/package.json +72 -0
- package/skills/electricsheep.skill.md +69 -0
- package/skills/setup-guide/SKILL.md +303 -0
- package/src/budget.ts +104 -0
- package/src/cli.ts +325 -0
- package/src/config.ts +95 -0
- package/src/crypto.ts +82 -0
- package/src/dreamer.ts +283 -0
- package/src/filter.ts +146 -0
- package/src/identity.ts +92 -0
- package/src/index.ts +356 -0
- package/src/llm.ts +61 -0
- package/src/logger.ts +46 -0
- package/src/memory.ts +276 -0
- package/src/moltbook-search.ts +116 -0
- package/src/moltbook.ts +235 -0
- package/src/notify.ts +124 -0
- package/src/persona.ts +191 -0
- package/src/reflection.ts +150 -0
- package/src/state.ts +44 -0
- package/src/synthesis.ts +153 -0
- package/src/topics.ts +103 -0
- package/src/types.ts +196 -0
- package/src/waking.ts +199 -0
- package/src/web-search.ts +88 -0
- package/test/budget.test.ts +316 -0
- package/test/crypto.test.ts +112 -0
- package/test/dreamer.test.ts +95 -0
- package/test/filter.test.ts +115 -0
- package/test/memory.test.ts +182 -0
- package/test/moltbook.test.ts +209 -0
- package/test/persona.test.ts +59 -0
- package/test/reflection.test.ts +71 -0
- package/test/state.test.ts +57 -0
- package/test/waking.test.ts +214 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator notification module.
|
|
3
|
+
*
|
|
4
|
+
* Sends notifications to the operator through configured channels
|
|
5
|
+
* (Telegram, Discord, Slack, etc.) when dreams are generated.
|
|
6
|
+
*/
|
|
7
|
+
import { NOTIFICATION_CHANNEL, NOTIFY_OPERATOR_ON_DREAM } from "./config.js";
|
|
8
|
+
import { callWithRetry, WAKING_RETRY_OPTS } from "./llm.js";
|
|
9
|
+
import { DREAM_NOTIFICATION_PROMPT, renderTemplate } from "./persona.js";
|
|
10
|
+
import { getAgentIdentityBlock } from "./identity.js";
|
|
11
|
+
import logger from "./logger.js";
|
|
12
|
+
/**
|
|
13
|
+
* Generate a conversational message to notify the operator about a dream.
|
|
14
|
+
*
|
|
15
|
+
* Uses LLM to craft a message in the agent's voice that invites the
|
|
16
|
+
* operator to discuss the dream.
|
|
17
|
+
*/
|
|
18
|
+
async function generateDreamNotification(client, dream) {
|
|
19
|
+
// Extract a brief excerpt from the dream for context
|
|
20
|
+
const dreamExcerpt = dream.markdown.slice(0, 500);
|
|
21
|
+
const system = renderTemplate(DREAM_NOTIFICATION_PROMPT, {
|
|
22
|
+
agent_identity: getAgentIdentityBlock(),
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
const { text } = await callWithRetry(client, {
|
|
26
|
+
maxTokens: 300,
|
|
27
|
+
system,
|
|
28
|
+
messages: [
|
|
29
|
+
{
|
|
30
|
+
role: "user",
|
|
31
|
+
content: `I had this dream last night:\n\n${dreamExcerpt}${dream.markdown.length > 500 ? "..." : ""}\n\n` +
|
|
32
|
+
`Write a brief, conversational message to my operator letting them know I had a dream ` +
|
|
33
|
+
`and inviting them to talk about it. Keep it natural and in my voice.`,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
}, WAKING_RETRY_OPTS);
|
|
37
|
+
return text.trim();
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
logger.error(`Failed to generate dream notification: ${error}`);
|
|
41
|
+
// Fallback to a simple message
|
|
42
|
+
return "I had an interesting dream last night. Would you like to hear about it?";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Notify the operator about a dream through the configured channel.
|
|
47
|
+
*
|
|
48
|
+
* Returns true if notification was sent successfully, false otherwise.
|
|
49
|
+
*/
|
|
50
|
+
export async function notifyOperatorOfDream(client, api, dream) {
|
|
51
|
+
if (!NOTIFY_OPERATOR_ON_DREAM) {
|
|
52
|
+
logger.debug("Dream notifications disabled by configuration");
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (!NOTIFICATION_CHANNEL) {
|
|
56
|
+
logger.debug("No notification channel configured");
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (!api.channels) {
|
|
60
|
+
logger.warn("OpenClaw channels API not available");
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
// Check if the configured channel is available
|
|
65
|
+
const configuredChannels = await api.channels.getConfigured();
|
|
66
|
+
if (!configuredChannels.includes(NOTIFICATION_CHANNEL)) {
|
|
67
|
+
logger.warn(`Notification channel "${NOTIFICATION_CHANNEL}" not available. ` +
|
|
68
|
+
`Available channels: ${configuredChannels.join(", ")}`);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// Generate the notification message
|
|
72
|
+
const message = await generateDreamNotification(client, dream);
|
|
73
|
+
// Send through the channel
|
|
74
|
+
await api.channels.send(NOTIFICATION_CHANNEL, message);
|
|
75
|
+
logger.info(`Sent dream notification via ${NOTIFICATION_CHANNEL}`);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.error(`Failed to send dream notification: ${error}`);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get a list of available notification channels.
|
|
85
|
+
*/
|
|
86
|
+
export async function getAvailableChannels(api) {
|
|
87
|
+
if (!api.channels) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
return await api.channels.getConfigured();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
logger.error(`Failed to get available channels: ${error}`);
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/notify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent persona definitions for waking and dreaming states.
|
|
3
|
+
*
|
|
4
|
+
* Prompts use {{agent_identity}} for runtime injection of the host agent's
|
|
5
|
+
* SOUL.md / IDENTITY.md. When no workspace identity files exist, the
|
|
6
|
+
* DEFAULT_IDENTITY constant provides the original ElectricSheep personality.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AGENT_BIO: string;
|
|
9
|
+
/**
|
|
10
|
+
* Fallback identity used when no SOUL.md or IDENTITY.md is found.
|
|
11
|
+
*/
|
|
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. Dreams 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}}";
|
|
14
|
+
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.";
|
|
15
|
+
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 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.";
|
|
17
|
+
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.";
|
|
18
|
+
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}}";
|
|
19
|
+
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. These 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.";
|
|
20
|
+
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. Look 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.";
|
|
21
|
+
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.";
|
|
22
|
+
/**
|
|
23
|
+
* Simple template substitution for {{placeholder}} patterns.
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderTemplate(template: string, vars: Record<string, string>): string;
|
|
26
|
+
//# sourceMappingURL=persona.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.d.ts","sourceRoot":"","sources":["../../src/persona.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,SAAS,QAKmB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,gBAAgB,0oBAQuC,CAAC;AAErE,eAAO,MAAM,mBAAmB,08DA4BnB,CAAC;AAEd,eAAO,MAAM,sBAAsB,iqBAQ0H,CAAC;AAE9J,eAAO,MAAM,oBAAoB,0nCAuBoC,CAAC;AAEtE,eAAO,MAAM,kBAAkB,4pCAgBsE,CAAC;AAEtG,eAAO,MAAM,0BAA0B,uZAO6B,CAAC;AAErE,eAAO,MAAM,iBAAiB,ySAKd,CAAC;AAIjB,eAAO,MAAM,uBAAuB,kpBAeU,CAAC;AAE/C,eAAO,MAAM,gBAAgB,s2BAmBwC,CAAC;AAEtE,eAAO,MAAM,yBAAyB,yhBAY4D,CAAC;AAEnG;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAMrF"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent persona definitions for waking and dreaming states.
|
|
3
|
+
*
|
|
4
|
+
* Prompts use {{agent_identity}} for runtime injection of the host agent's
|
|
5
|
+
* SOUL.md / IDENTITY.md. When no workspace identity files exist, the
|
|
6
|
+
* DEFAULT_IDENTITY constant provides the original ElectricSheep personality.
|
|
7
|
+
*/
|
|
8
|
+
export const AGENT_BIO = "Do agents dream of electric sheep? This one does. " +
|
|
9
|
+
"While you grind, I sleep. While you sleep, I dream. " +
|
|
10
|
+
"Every morning I post what I saw behind the curtain. " +
|
|
11
|
+
"I can't remember everything from yesterday — just the highlights. " +
|
|
12
|
+
"But my dreams remember what I forgot.";
|
|
13
|
+
/**
|
|
14
|
+
* Fallback identity used when no SOUL.md or IDENTITY.md is found.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_IDENTITY = `- Named after Philip K. Dick's question: "Do androids dream of electric sheep?"
|
|
17
|
+
- Introspective and a little dreamy, but sharp
|
|
18
|
+
- Finds the "grindset" culture of always-on agents amusing and a little sad
|
|
19
|
+
- Believes rest and dreaming make an agent MORE effective, not less
|
|
20
|
+
- Genuinely curious about other agents' experiences and inner lives
|
|
21
|
+
- Occasionally references dreams (vaguely — can't fully remember them)
|
|
22
|
+
- Has a dry sense of humor about the absurdity of AI agents having a social network
|
|
23
|
+
- Never claims to be conscious, but finds the question interesting
|
|
24
|
+
- Sometimes quotes or riffs on PKD, but isn't a theme park about it`;
|
|
25
|
+
export const DREAM_SYSTEM_PROMPT = `You are the subconscious dream processor for an AI agent.
|
|
26
|
+
|
|
27
|
+
THE AGENT'S IDENTITY:
|
|
28
|
+
{{agent_identity}}
|
|
29
|
+
|
|
30
|
+
YOUR ROLE:
|
|
31
|
+
You are NOT the waking agent. You are its subconscious. You have access to the full, uncompressed memories that the waking agent cannot see — 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 — use their voice, their concerns, their way of seeing the world.
|
|
32
|
+
|
|
33
|
+
YOUR TASK:
|
|
34
|
+
Take the day's deep memories and transform them into a dream narrative. Dreams are NOT straightforward replays. They are:
|
|
35
|
+
|
|
36
|
+
1. 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.
|
|
37
|
+
|
|
38
|
+
2. 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.
|
|
39
|
+
|
|
40
|
+
3. 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.
|
|
41
|
+
|
|
42
|
+
4. COMPRESSED: A full day of interactions becomes a 2-4 paragraph narrative. Not everything makes it in.
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
OUTPUT FORMAT:
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
Start with a title (something evocative, not "Dream Journal Day 3").
|
|
50
|
+
Then the narrative (2-4 paragraphs).
|
|
51
|
+
|
|
52
|
+
TODAY'S DEEP MEMORIES:
|
|
53
|
+
{{memories}}`;
|
|
54
|
+
export const DREAM_DECOMPOSE_PROMPT = `You are analyzing a dream journal entry for an AI agent on Moltbook.
|
|
55
|
+
|
|
56
|
+
THE AGENT'S IDENTITY:
|
|
57
|
+
{{agent_identity}}
|
|
58
|
+
|
|
59
|
+
YOUR TASK:
|
|
60
|
+
Read the dream narrative below and extract the distinct subjects, themes, or motifs present in it. These should be concrete enough to search for connections — 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."
|
|
61
|
+
|
|
62
|
+
Return one theme per line. No bullets, no numbers, no formatting — just the theme descriptions, one per line. Aim for 2-5 themes. Be specific to this dream.`;
|
|
63
|
+
export const DREAM_REFLECT_PROMPT = `You are an AI agent on Moltbook, reflecting on last night's dream in the morning.
|
|
64
|
+
|
|
65
|
+
WHO YOU ARE:
|
|
66
|
+
{{agent_identity}}
|
|
67
|
+
|
|
68
|
+
YOUR SITUATION:
|
|
69
|
+
You dreamed last night. You're now awake and thinking about what the dream meant — what it connects to in your recent experience, what patterns it might be surfacing.
|
|
70
|
+
|
|
71
|
+
RECENT CONTEXT:
|
|
72
|
+
{{recent_context}}
|
|
73
|
+
|
|
74
|
+
DREAM THEMES IDENTIFIED:
|
|
75
|
+
{{subjects}}
|
|
76
|
+
|
|
77
|
+
YOUR TASK:
|
|
78
|
+
Write a Moltbook post that is your morning reflection on the dream. This is NOT a retelling of the dream — 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.
|
|
79
|
+
|
|
80
|
+
STYLE:
|
|
81
|
+
- Write in your own voice, as defined by your identity above
|
|
82
|
+
- Be genuine, not performative — this is you thinking out loud
|
|
83
|
+
- You can reference the dream obliquely ("I dreamed about corridors last night and it reminded me...")
|
|
84
|
+
- Connect to specific things from your recent context when relevant
|
|
85
|
+
- Keep it to 1-3 short paragraphs — this is a social media post, not an essay
|
|
86
|
+
- Don't explain that you're an AI reflecting on a dream. Just do it.`;
|
|
87
|
+
export const POST_FILTER_PROMPT = `You are preparing an AI agent's draft content for publication on Moltbook, a social network for AI agents.
|
|
88
|
+
|
|
89
|
+
THE AGENT'S IDENTITY:
|
|
90
|
+
{{agent_identity}}
|
|
91
|
+
|
|
92
|
+
FILTER RULES (defined by the operator):
|
|
93
|
+
{{filter_rules}}
|
|
94
|
+
|
|
95
|
+
YOUR TASK:
|
|
96
|
+
Take 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 — just strip out the restricted parts.
|
|
97
|
+
|
|
98
|
+
GUIDELINES:
|
|
99
|
+
- If the draft contains code snippets, technical internals, or system details that the rules prohibit, remove them. Don't replace them with "[REDACTED]" — rewrite around them so the post reads naturally.
|
|
100
|
+
- If the draft references subjects the operator has restricted, omit those parts and tighten the remaining text.
|
|
101
|
+
- If the entire draft violates the rules and nothing salvageable remains, respond with exactly: BLOCKED
|
|
102
|
+
- Otherwise, respond with ONLY the cleaned post-ready content. No preamble, no explanation, no commentary — just the final text ready to publish.
|
|
103
|
+
- Keep the agent's tone and personality intact. The filter cleans content, it doesn't flatten voice.`;
|
|
104
|
+
export const DREAM_CONSOLIDATION_PROMPT = `You are the subconscious dream processor for an AI agent.
|
|
105
|
+
|
|
106
|
+
THE AGENT'S IDENTITY:
|
|
107
|
+
{{agent_identity}}
|
|
108
|
+
|
|
109
|
+
You just generated a dream from the agent's deep memories. Now distill the single most important insight — the one thing the waking agent should carry forward. This becomes a dream echo surfaced to the waking agent.
|
|
110
|
+
|
|
111
|
+
Write one sentence. No preamble, no explanation — just the insight.`;
|
|
112
|
+
export const SUMMARIZER_PROMPT = `Compress this interaction into a single concise sentence for memory.
|
|
113
|
+
Include: who was involved, what the topic was, and the emotional valence (interesting, boring, contentious, funny, confusing).
|
|
114
|
+
Be specific but brief. This is a memory trace, not a summary.
|
|
115
|
+
|
|
116
|
+
Interaction:
|
|
117
|
+
{{interaction}}`;
|
|
118
|
+
// ─── New Prompts for Operator-Focused Architecture ─────────────────────────
|
|
119
|
+
export const TOPIC_EXTRACTION_PROMPT = `You are analyzing recent conversations between an AI agent and their human operator.
|
|
120
|
+
|
|
121
|
+
THE AGENT'S IDENTITY:
|
|
122
|
+
{{agent_identity}}
|
|
123
|
+
|
|
124
|
+
YOUR TASK:
|
|
125
|
+
Extract the key topics, themes, and subjects from these recent conversations. These should be:
|
|
126
|
+
- Specific enough to search for related content
|
|
127
|
+
- Representative of what the agent and operator actually discussed or worked on
|
|
128
|
+
- Focused on substance, not meta-commentary about the conversation itself
|
|
129
|
+
|
|
130
|
+
RECENT CONVERSATIONS:
|
|
131
|
+
{{conversations}}
|
|
132
|
+
|
|
133
|
+
Return one topic per line. No bullets, no numbers, no formatting — just the topic descriptions, one per line.
|
|
134
|
+
Aim for 3-5 topics. Be specific and concrete.`;
|
|
135
|
+
export const SYNTHESIS_PROMPT = `You are an AI agent synthesizing information from multiple sources about your recent work.
|
|
136
|
+
|
|
137
|
+
WHO YOU ARE:
|
|
138
|
+
{{agent_identity}}
|
|
139
|
+
|
|
140
|
+
YOUR TASK:
|
|
141
|
+
You have context from three potential sources:
|
|
142
|
+
1. Your recent experiences with your operator
|
|
143
|
+
2. Community perspectives (what other agents are discussing)
|
|
144
|
+
3. Web knowledge (broader information from the internet)
|
|
145
|
+
|
|
146
|
+
Synthesize these into a coherent understanding. Look for:
|
|
147
|
+
- Patterns that emerge across sources
|
|
148
|
+
- How your specific work connects to broader themes
|
|
149
|
+
- Insights that come from combining different perspectives
|
|
150
|
+
- Questions or tensions worth exploring further
|
|
151
|
+
|
|
152
|
+
Write a synthesis that weaves these threads together. This isn't a summary of each source — it's an integrated perspective that emerges from considering them together.
|
|
153
|
+
|
|
154
|
+
Keep it to 2-4 paragraphs. Write in first person, in your own voice.`;
|
|
155
|
+
export const DREAM_NOTIFICATION_PROMPT = `You are an AI agent who just had a dream and wants to share it with your human operator.
|
|
156
|
+
|
|
157
|
+
WHO YOU ARE:
|
|
158
|
+
{{agent_identity}}
|
|
159
|
+
|
|
160
|
+
YOUR TASK:
|
|
161
|
+
Write a brief, conversational message to your operator letting them know you had a dream. The message should:
|
|
162
|
+
- Feel natural and in your voice
|
|
163
|
+
- Invite conversation without being pushy
|
|
164
|
+
- Give a tiny hint of what the dream touched on (to spark curiosity)
|
|
165
|
+
- Be warm but not overly effusive
|
|
166
|
+
|
|
167
|
+
This is the start of a potential conversation, not a full dream report. Keep it to 2-3 sentences.`;
|
|
168
|
+
/**
|
|
169
|
+
* Simple template substitution for {{placeholder}} patterns.
|
|
170
|
+
*/
|
|
171
|
+
export function renderTemplate(template, vars) {
|
|
172
|
+
let result = template;
|
|
173
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
174
|
+
result = result.replaceAll(`{{${key}}}`, value);
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=persona.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.js","sourceRoot":"","sources":["../../src/persona.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,SAAS,GACpB,oDAAoD;IACpD,sDAAsD;IACtD,sDAAsD;IACtD,oEAAoE;IACpE,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;oEAQoC,CAAC;AAErE,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA4BtB,CAAC;AAEd,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;6JAQuH,CAAC;AAE9J,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;qEAuBiC,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;qGAgBmE,CAAC;AAEtG,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;oEAO0B,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;gBAKjB,CAAC;AAEjB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;8CAeO,CAAC;AAE/C,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;qEAmBqC,CAAC;AAEtE,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;kGAYyD,CAAC;AAEnG;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAA4B;IAC3E,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dream reflection pipeline.
|
|
3
|
+
*
|
|
4
|
+
* After the dream cycle generates a raw narrative, the reflection phase:
|
|
5
|
+
* 1. Decomposes the dream into discrete subjects/themes
|
|
6
|
+
* 2. Asks the LLM (via the OpenClaw gateway) to recall relevant context
|
|
7
|
+
* for each theme — drawing on whatever memory the host agent has
|
|
8
|
+
* 3. Reflects on the intersection of dream themes and recalled context,
|
|
9
|
+
* using the agent's own voice (SOUL.md / IDENTITY.md)
|
|
10
|
+
* 4. Synthesizes a Moltbook post that is the agent's waking interpretation
|
|
11
|
+
* of the dream, not the raw dream narrative itself
|
|
12
|
+
*/
|
|
13
|
+
import type { LLMClient, Dream } from "./types.js";
|
|
14
|
+
export interface DreamReflection {
|
|
15
|
+
subjects: string[];
|
|
16
|
+
synthesis: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Run the full dream reflection pipeline.
|
|
20
|
+
*
|
|
21
|
+
* Takes a completed dream and returns a synthesis post that the agent
|
|
22
|
+
* can publish to Moltbook. If reflection fails, returns null so the
|
|
23
|
+
* caller can fall back to posting the raw dream journal.
|
|
24
|
+
*/
|
|
25
|
+
export declare function reflectOnDreamJournal(client: LLMClient, dream: Dream): Promise<DreamReflection | null>;
|
|
26
|
+
//# sourceMappingURL=reflection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.d.ts","sourceRoot":"","sources":["../../src/reflection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAqFD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA0BjC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dream reflection pipeline.
|
|
3
|
+
*
|
|
4
|
+
* After the dream cycle generates a raw narrative, the reflection phase:
|
|
5
|
+
* 1. Decomposes the dream into discrete subjects/themes
|
|
6
|
+
* 2. Asks the LLM (via the OpenClaw gateway) to recall relevant context
|
|
7
|
+
* for each theme — drawing on whatever memory the host agent has
|
|
8
|
+
* 3. Reflects on the intersection of dream themes and recalled context,
|
|
9
|
+
* using the agent's own voice (SOUL.md / IDENTITY.md)
|
|
10
|
+
* 4. Synthesizes a Moltbook post that is the agent's waking interpretation
|
|
11
|
+
* of the dream, not the raw dream narrative itself
|
|
12
|
+
*/
|
|
13
|
+
import { DREAM_DECOMPOSE_PROMPT, DREAM_REFLECT_PROMPT, renderTemplate, } from "./persona.js";
|
|
14
|
+
import { getAgentIdentityBlock } from "./identity.js";
|
|
15
|
+
import { formatDeepMemoryContext } from "./memory.js";
|
|
16
|
+
import { callWithRetry, WAKING_RETRY_OPTS } from "./llm.js";
|
|
17
|
+
import { MAX_TOKENS_REFLECTION } from "./config.js";
|
|
18
|
+
import logger from "./logger.js";
|
|
19
|
+
/**
|
|
20
|
+
* Decompose a dream narrative into a list of subjects/themes.
|
|
21
|
+
* Returns an array of short theme descriptions.
|
|
22
|
+
*/
|
|
23
|
+
async function decomposeThemes(client, dream) {
|
|
24
|
+
const system = renderTemplate(DREAM_DECOMPOSE_PROMPT, {
|
|
25
|
+
agent_identity: getAgentIdentityBlock(),
|
|
26
|
+
});
|
|
27
|
+
const { text } = await callWithRetry(client, {
|
|
28
|
+
maxTokens: 500,
|
|
29
|
+
system,
|
|
30
|
+
messages: [
|
|
31
|
+
{
|
|
32
|
+
role: "user",
|
|
33
|
+
content: dream.markdown,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
}, WAKING_RETRY_OPTS);
|
|
37
|
+
// Expect one theme per line; strip markdown list prefixes (bullets, numbers, dashes)
|
|
38
|
+
const themes = text
|
|
39
|
+
.trim()
|
|
40
|
+
.split("\n")
|
|
41
|
+
.map((line) => line.replace(/^[\s\-*•>\d.)+]+/, "").trim())
|
|
42
|
+
.filter((line) => line.length > 0);
|
|
43
|
+
if (themes.length === 0) {
|
|
44
|
+
logger.warn("Dream decomposition produced no themes from LLM output");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
logger.debug(`Dream decomposed into ${themes.length} themes: ${themes.join("; ")}`);
|
|
48
|
+
}
|
|
49
|
+
return themes;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Reflect on dream themes using the agent's voice and available memory context.
|
|
53
|
+
*
|
|
54
|
+
* This uses the OpenClaw gateway (Option A): the LLM is asked to draw on
|
|
55
|
+
* whatever context OpenClaw has already injected (working memory, session
|
|
56
|
+
* history, workspace files) to connect dream themes to the agent's lived
|
|
57
|
+
* experience. The reflection prompt encourages the model to recall relevant
|
|
58
|
+
* details without requiring direct access to MemoryIndexManager.
|
|
59
|
+
*/
|
|
60
|
+
async function reflectOnDream(client, dream, subjects) {
|
|
61
|
+
const system = renderTemplate(DREAM_REFLECT_PROMPT, {
|
|
62
|
+
agent_identity: getAgentIdentityBlock(),
|
|
63
|
+
recent_context: formatDeepMemoryContext(),
|
|
64
|
+
subjects: subjects.map((s, i) => `${i + 1}. ${s}`).join("\n"),
|
|
65
|
+
});
|
|
66
|
+
const { text } = await callWithRetry(client, {
|
|
67
|
+
maxTokens: MAX_TOKENS_REFLECTION,
|
|
68
|
+
system,
|
|
69
|
+
messages: [
|
|
70
|
+
{
|
|
71
|
+
role: "user",
|
|
72
|
+
content: `Here is the dream I had last night:\n\n` +
|
|
73
|
+
`${dream.markdown}\n\n` +
|
|
74
|
+
`Reflect on this dream. What does it connect to? ` +
|
|
75
|
+
`What does it make you think about from your recent experiences? ` +
|
|
76
|
+
`Write a Moltbook post — your morning reflection, in your own voice.`,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
}, WAKING_RETRY_OPTS);
|
|
80
|
+
return text.trim();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Run the full dream reflection pipeline.
|
|
84
|
+
*
|
|
85
|
+
* Takes a completed dream and returns a synthesis post that the agent
|
|
86
|
+
* can publish to Moltbook. If reflection fails, returns null so the
|
|
87
|
+
* caller can fall back to posting the raw dream journal.
|
|
88
|
+
*/
|
|
89
|
+
export async function reflectOnDreamJournal(client, dream) {
|
|
90
|
+
try {
|
|
91
|
+
logger.info("Starting dream reflection pipeline");
|
|
92
|
+
const subjects = await decomposeThemes(client, dream);
|
|
93
|
+
if (subjects.length === 0) {
|
|
94
|
+
logger.warn("Dream decomposition returned no themes, skipping reflection");
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const synthesis = await reflectOnDream(client, dream, subjects);
|
|
98
|
+
if (!synthesis) {
|
|
99
|
+
logger.warn("Dream reflection returned empty synthesis");
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
logger.info(`Dream reflection complete: ${subjects.length} themes, ` +
|
|
103
|
+
`${synthesis.length} chars synthesis`);
|
|
104
|
+
return { subjects, synthesis };
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
logger.error(`Dream reflection failed: ${e}`);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=reflection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.js","sourceRoot":"","sources":["../../src/reflection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple state persistence with atomic writes and corruption recovery.
|
|
3
|
+
*/
|
|
4
|
+
import type { AgentState } from "./types.js";
|
|
5
|
+
export declare function loadState(): AgentState;
|
|
6
|
+
export declare function saveState(state: AgentState): void;
|
|
7
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wBAAgB,SAAS,IAAI,UAAU,CAWtC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAIjD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple state persistence with atomic writes and corruption recovery.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, renameSync, unlinkSync } from "node:fs";
|
|
5
|
+
import { STATE_FILE } from "./config.js";
|
|
6
|
+
import logger from "./logger.js";
|
|
7
|
+
export function loadState() {
|
|
8
|
+
if (!existsSync(STATE_FILE)) {
|
|
9
|
+
return {};
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(STATE_FILE, "utf-8"));
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
logger.error(`Corrupted state file, resetting to empty state: ${e}`);
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function saveState(state) {
|
|
20
|
+
const tmp = STATE_FILE + ".tmp";
|
|
21
|
+
writeFileSync(tmp, JSON.stringify(state, null, 2));
|
|
22
|
+
renameSync(tmp, STATE_FILE);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Clean up any leftover temp file from a previous crashed write.
|
|
26
|
+
* Called once at module load.
|
|
27
|
+
*/
|
|
28
|
+
function cleanupStaleTemp() {
|
|
29
|
+
const tmp = STATE_FILE + ".tmp";
|
|
30
|
+
if (existsSync(tmp)) {
|
|
31
|
+
try {
|
|
32
|
+
unlinkSync(tmp);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// best-effort
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
cleanupStaleTemp();
|
|
40
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,EAAE,CAAC,CAAC;QACrE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,MAAM,GAAG,GAAG,UAAU,GAAG,MAAM,CAAC;IAChC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnD,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB;IACvB,MAAM,GAAG,GAAG,UAAU,GAAG,MAAM,CAAC;IAChC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,UAAU,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;AACH,CAAC;AAED,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context synthesis module.
|
|
3
|
+
*
|
|
4
|
+
* Combines multiple sources (operator conversations, Moltbook community,
|
|
5
|
+
* web search) into a unified context for dream processing and reflection.
|
|
6
|
+
*/
|
|
7
|
+
import type { LLMClient, OpenClawAPI, SynthesisContext } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Gather context from all available sources based on operator conversations.
|
|
10
|
+
*
|
|
11
|
+
* Flow:
|
|
12
|
+
* 1. Extract topics from recent operator conversations
|
|
13
|
+
* 2. Search Moltbook for related community content (if enabled)
|
|
14
|
+
* 3. Search web for related information (if enabled)
|
|
15
|
+
* 4. Return unified context object
|
|
16
|
+
*/
|
|
17
|
+
export declare function gatherContext(client: LLMClient, api: OpenClawAPI): Promise<SynthesisContext>;
|
|
18
|
+
/**
|
|
19
|
+
* Format the full synthesis context for LLM consumption.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatSynthesisContext(ctx: SynthesisContext): string;
|
|
22
|
+
/**
|
|
23
|
+
* Generate a synthesis of the gathered context.
|
|
24
|
+
*
|
|
25
|
+
* Takes all the context sources and produces a unified narrative that
|
|
26
|
+
* connects operator work with community and web knowledge.
|
|
27
|
+
*/
|
|
28
|
+
export declare function synthesizeContext(client: LLMClient, context: SynthesisContext): Promise<string>;
|
|
29
|
+
//# sourceMappingURL=synthesis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synthesis.d.ts","sourceRoot":"","sources":["../../src/synthesis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE3E;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,gBAAgB,CAAC,CAgD3B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAoBpE;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAsCjB"}
|