From 6535ad597fc54e19ca09654bb6f95b79abecea58 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Thu, 12 Feb 2026 16:17:32 -0500 Subject: [PATCH] fix: use event.prompt instead of ctx.sessionKey for prompt storage in OpenClaw plugin The before_agent_start handler was passing ctx.sessionKey (e.g. "agent:main:main") as the prompt to the worker API, causing the viewer to display the session key instead of actual user prompt text. Now correctly reads event.prompt from OpenClaw's BeforeAgentStartEvent. Also adds message_received hook to capture inbound user prompts from messaging channels (Telegram, Discord, etc.) and stores them via the worker API. Co-Authored-By: Claude Opus 4.6 --- openclaw/src/index.ts | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/openclaw/src/index.ts b/openclaw/src/index.ts index ea33da74..ec5e36a5 100644 --- a/openclaw/src/index.ts +++ b/openclaw/src/index.ts @@ -67,13 +67,27 @@ interface SessionEndEvent { durationMs?: number; } +interface MessageReceivedEvent { + from: string; + content: string; + timestamp?: number; + metadata?: Record; +} + interface EventContext { sessionKey?: string; workspaceDir?: string; agentId?: string; } +interface MessageContext { + channelId: string; + accountId?: string; + conversationId?: string; +} + type EventCallback = (event: T, ctx: EventContext) => void | Promise; +type MessageEventCallback = (event: T, ctx: MessageContext) => void | Promise; interface OpenClawPluginApi { id: string; @@ -100,6 +114,7 @@ interface OpenClawPluginApi { ((event: "agent_end", callback: EventCallback) => void) & ((event: "session_start", callback: EventCallback) => void) & ((event: "session_end", callback: EventCallback) => void) & + ((event: "message_received", callback: MessageEventCallback) => void) & ((event: "after_compaction", callback: EventCallback) => void) & ((event: "gateway_start", callback: EventCallback>) => void); runtime: { @@ -482,6 +497,20 @@ export default function claudeMemPlugin(api: OpenClawPluginApi): void { api.logger.info(`[claude-mem] Session initialized: ${contentSessionId}`); }); + // ------------------------------------------------------------------ + // Event: message_received — capture inbound user prompts from channels + // ------------------------------------------------------------------ + api.on("message_received", async (event, ctx) => { + const sessionKey = ctx.conversationId || ctx.channelId || "default"; + const contentSessionId = getContentSessionId(sessionKey); + + await workerPost(workerPort, "/api/sessions/init", { + contentSessionId, + project: baseProjectName, + prompt: event.content || "[media prompt]", + }, api.logger); + }); + // ------------------------------------------------------------------ // Event: after_compaction — re-init session after context compaction // ------------------------------------------------------------------ @@ -500,7 +529,7 @@ export default function claudeMemPlugin(api: OpenClawPluginApi): void { // ------------------------------------------------------------------ // Event: before_agent_start — init session + sync MEMORY.md + track workspace // ------------------------------------------------------------------ - api.on("before_agent_start", async (_event, ctx) => { + api.on("before_agent_start", async (event, ctx) => { // Track workspace dir so tool_result_persist can sync MEMORY.md later if (ctx.workspaceDir) { workspaceDirsBySessionKey.set(ctx.sessionKey || "default", ctx.workspaceDir); @@ -512,7 +541,7 @@ export default function claudeMemPlugin(api: OpenClawPluginApi): void { await workerPost(workerPort, "/api/sessions/init", { contentSessionId, project: getProjectName(ctx), - prompt: ctx.sessionKey || "agent run", + prompt: event.prompt || "agent run", }, api.logger); // Sync MEMORY.md before agent runs (provides context to agent)