Skip to content

Continuity retrieval/intent broken due to before_agent_start event shape; fix by using event.prompt + preserve newlines; reduce noisy ERROR logs #8

@davidrobertson

Description

@davidrobertson

Problem

On some surfaces (Discord + Control UI webchat in our case), the before_agent_start hook is firing with:

event.messages empty (or missing)
no event.message / event.text
only event.prompt present

Because Continuity was extracting the “last user message” exclusively from event.messages, cleanUserText frequently ended up empty, which caused:
intent detection to stay effectively “false/never triggers”
retrieval/search to not run (or to run with an empty query)

We confirmed via logs that the hook payload sometimes looked like:
event.keys=prompt and messages=0

Fixes implemented

  1. Fallback user text extraction in before_agent_start

In our OpenClaw setup, we updated Continuity to derive the user text from additional fields when event.messages is empty.
In our environment the only reliable field was event.prompt, so we added it as the last-resort fallback:
event.inputText || event.userText || event.text || event.prompt || ''

Result: before_agent_start now consistently sees non-empty user text even when event.messages is empty, and retrieval can run.

  1. Preserve newlines when content arrives as an array

_extractText(msg) previously joined msg.content[] with spaces, which collapses multi-line messages (including injected context blocks) into a single line.
This broke _stripContextBlocks() because the “context blocks” were no longer line-delimited, causing stripping to over-remove and produce an empty string.
Changed join behavior to use \n instead of ' ' to preserve line boundaries.

Result: context stripping can reliably remove injected [CONTINUITY CONTEXT] / metadata blocks while leaving the actual user query intact.

  1. Safety fallback when context stripping returns empty

When _stripContextBlocks() returns "" but the raw text is non-empty (common when messages are heavily wrapped), we added a fallback that extracts trailing non-context lines (so intent detection doesn’t get permanently stuck).
4) Logging cleanup

Some retrieval status lines were being emitted via console.error, polluting logs as “ERROR” during normal operation.
Downgraded those to api.logger.debug (or similar) so they only appear when debugging is enabled.

Files changed

extensions/openclaw-plugin-continuity/index.js
updated user-text extraction for before_agent_start
_extractText() newline join change
fallback extraction when stripping yields empty
log level cleanup (console.error → debug logger)

How to reproduce

  1. Use a channel/surface where before_agent_start doesn’t populate event.messages (messages=0).
  2. Ask a recall-style question, e.g. “do you remember what we changed…”
  3. Observe Continuity logs showing event.keys=prompt and missing user text prior to the patch.
  4. After patch: observe before_agent_start userTextLen>0 and retrieval executing.

Expected outcome after patch

Continuity can run intent detection + retrieval even when event.messages is empty.
Retrieval queries are non-empty and stable.
Logs are readable (no “ERROR” spam for normal retrieval telemetry).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions