Skip to content

Group chats: attach sender to LLM messages array entries so attribution survives the rolling context window #77355

@kydorn

Description

@kydorn

Context

This is a follow-up to #77346, which was closed by ClawSweeper as "already implemented" pointing to buildInboundUserContextPrefix in src/auto-reply/reply/inbound-meta.ts. That analysis is correct for the current turn — but misses a gap that surfaces specifically with contextInjection: "continuation-skip".

The gap

With continuation-skip, openclaw does not re-inject conversation history into each new agent run. Previous turns sit in the model's rolling context window as plain body text — the structured metadata blocks (Sender (untrusted metadata):, Chat history since last reply:) that accompanied those turns are not re-injected alongside them. So the model can see what was said in prior turns but not who said it.

The structured metadata path correctly attributes the current turn. It does not make attribution durable across the context window.

Concrete example

Group chat between Alice, Bob, and Carol with contextInjection: "continuation-skip":

  1. Alice: "Can someone help with X?" → agent replies
  2. Bob: "I tried Y but it didn't work" → agent replies
  3. Carol: "I agree with Bob" → agent replies

At turn 3, turns 1 and 2 are in the context window as raw body text with no sender prefix. The agent cannot tell it was Bob (not Alice) who tried Y, or confirm Carol is agreeing with Bob specifically. The structured block for turn 3 correctly identifies Carol as the current sender — but the history is opaque.

Why inline body prefixes complement the structured approach

Baking Alice: directly into BodyForAgent (which gets stored in the conversation transcript) means attribution persists in the rolling context window regardless of history re-injection. The two approaches are not mutually exclusive — they solve different layers of the same problem:

  • Structured metadata blocks → attribution for the current turn (prompt-injection safe, structured)
  • Inline body prefix → attribution that survives across the context window in the transcript

Suggested fix

A groupSenderPrefix option (defaulting to true for ChatType === "group") that inlines sender attribution into BodyForAgent and InboundHistory[].body:

BodyForAgent: isGroup && senderName
  ? `${senderName}: ${bodyText}`
  : bodyText,

This is exactly what ships in the existing inline-body envelope (Body/combinedBody already prepends sender via formatInboundEnvelope with senderLabel). The ask is to extend the same treatment to BodyForAgent so the transcript-stored version carries attribution too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions