Skip to content

iMessage: Include reply/thread context in incoming messages #10872

Description

@r80hk

iMessage: Include reply/thread context in incoming messages

Labels

enhancement, channel:imessage

Body

Problem

When a user replies to a specific message in iMessage (using the inline reply feature), the OpenClaw agent receives only the new message text with no context about which message was being replied to.

This makes conversations confusing — the agent cannot tell which of its prior messages the user is responding to. Every other major channel (Telegram, Discord, Signal, WhatsApp) correctly passes reply context to the agent.

Current Behavior

User replies to a specific agent message in iMessage → Agent sees:

[iMessage from +1555…]
Yes, that one

Expected Behavior

User replies to a specific agent message in iMessage → Agent sees:

[iMessage from +1555…]
Yes, that one

[Replying to +17034055338 id:2320]
Here are two options: A) the blue one or B) the red one
[/Replying]

Technical Analysis

The OpenClaw iMessage integration has three layers: chat.db → imsg CLI → OpenClaw monitor → Agent.

✅ Layer 1: macOS Messages Database — HAS the data

The message table in chat.db has thread_originator_guid (reliable, matches iMessage UI) and reply_to_guid (less reliable). Verified with real data — multiple messages have thread_originator_guid correctly linking to their reply targets.

❌ Layer 2: imsg CLI v0.4.0 — Does NOT expose the data

Current imsg JSON output per message:

{
  "id": 2329,
  "text": "...",
  "guid": "E37CE941-...",
  "chat_id": 1,
  "created_at": "2026-02-06T23:16:42.284Z",
  "is_from_me": true,
  "sender": "+17034055338",
  "attachments": [],
  "reactions": []
}

No thread_originator_guid, reply_to_text, reply_to_sender, or reply_to_id fields.

Upstream work exists:

✅ Layer 3: OpenClaw Monitor — ALREADY has the code

The monitor (dist/imessage/monitor/monitor-provider.js) already implements reply context extraction:

function describeReplyContext(message) {
    const body = normalizeReplyField(message.reply_to_text);
    if (!body) return null;
    const id = normalizeReplyField(message.reply_to_id);
    const sender = normalizeReplyField(message.reply_to_sender);
    return { body, id, sender };
}

When reply context is present, it formats it as [Replying to <sender> id:<id>]\n<body>\n[/Replying] and populates ReplyToId, ReplyToBody, and ReplyToSender on the envelope.

The code is ready. The data just never arrives from imsg.

Comparison with Other Channels

Channel Reply Context How
Telegram grammY reply_to_message object
Discord message.reference → resolved message
Signal signal-cli quoteMessage
WhatsApp Baileys quotedMessage
iMessage imsg v0.4.0 doesn't emit reply fields

Proposed Solution

Option A (preferred — zero OpenClaw code changes):

  1. Upstream: Get imsg to include resolved reply context in its output:
    • reply_to_id — rowid of the originator message
    • reply_to_text — text of the originator message
    • reply_to_sender — sender of the originator message
  2. OpenClaw's existing describeReplyContext() picks these up automatically
  3. Bump imsg version requirement in docs

Option B (if imsg only adds the GUID):

  1. imsg PR Fix CI #39 adds thread_originator_guid
  2. OpenClaw resolves it by either:
    • Adding a message.get RPC method to imsg and calling it from the monitor
    • Querying chat.db directly (less ideal, duplicates DB access logic)
  3. Map resolved data into existing reply_to_text/reply_to_id/reply_to_sender fields

Dependencies

  • steipete/imsg#39 — PR adding thread_originator_guid (needs to be extended with resolved fields, or OpenClaw needs to handle resolution)

Additional Context

  • The reply_to_guid column in chat.db is unreliable — it often points to the most recent message rather than the actual reply target. thread_originator_guid is the correct field (per feat: add thread_originator_guid to message output imsg#39 analysis).
  • OpenClaw already supports replyToMode config for outbound replies on Telegram/Discord. Once inbound reply context works for iMessage, outbound replyToMode support could follow.
  • Full technical analysis: see projects/imessage-reply-context-analysis.md in the workspace.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.enhancementNew feature or request

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions