Skip to content

feat(webchat): reply-to a message with hydrated reply context#110791

Merged
fuller-stack-dev merged 5 commits into
mainfrom
feat/webchat-reply-context
Jul 18, 2026
Merged

feat(webchat): reply-to a message with hydrated reply context#110791
fuller-stack-dev merged 5 commits into
mainfrom
feat/webchat-reply-context

Conversation

@clawsweeper

@clawsweeper clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds reply-to support to the Control UI (webchat) chat, requested by maintainer Json in #maintainers: right-click a message → Reply sets a "Replying to …" chip above the composer (cancel with × or Escape), and the send now delivers the replied-to message to the agent as structured reply context instead of only an inline markdown quote.

This mirrors the Discord reply-context path from #90263 so agent-side handling stays channel-agnostic:

  • Frontend (ui/src/pages/chat/...): reply targets picked from persisted transcript messages now carry the transcript id (sourceMessageId). chat.send includes it as replyToId and skips the inline-quote fallback; targets without a persisted id (e.g. pending sends) keep the quote fallback. The id survives the durable offline outbox (composer-persistence).
  • Protocol (packages/gateway-protocol): ChatSendParamsSchema gains optional replyToId; regenerated Swift protocol models.
  • Gateway (src/gateway/server-methods/chat-send-reply-context.ts, wired in chat.ts): resolves the target message from session history via readSessionMessageByIdAsync and hydrates the channel-agnostic ReplyToId / ReplyToBody / ReplyToSender envelope fields in parallel with dispatch prep. Downstream this produces the same agent-facing metadata as Discord replies: reply_to_id and has_reply_context in "Conversation info", plus the untrusted "Reply target of current user message" block with sender label and body. Missing/unresolvable targets degrade to id-only, mirroring Discord's tolerance for omitted referenced messages; bodies are bounded to 2000 chars.
  • Docs: docs/web/webchat.md documents the flow.

Verification

  • node scripts/run-vitest.mjs src/gateway/server-methods/chat-send-reply-context.test.ts (new, 8 tests)
  • node scripts/run-vitest.mjs ui/src/pages/chat/chat-send.test.ts ui/src/pages/chat/composer-persistence.test.ts (262 tests, incl. new replyToId payload test)
  • node scripts/run-vitest.mjs on related suites: chat-send-request/user-turn/reply-dispatch, gateway-protocol index, chat.directive-tags, chat-send-dispatch-errors, chat.send-deleted-agent, chat-webchat-media, chat-send-command-replies, chat-thread/view/composer/pane/state (all green)
  • pnpm tsgo:core and pnpm tsgo:ui clean; oxlint on touched paths clean; pnpm protocol:gen/gen:swift/gen:kotlin regenerated; docs format check clean

🤖 Generated with Claude Code

Control UI replies now carry the target transcript id as replyToId on
chat.send. The Gateway resolves the replied-to message from session
history and hydrates the channel-agnostic ReplyToId/ReplyToBody/
ReplyToSender envelope fields, so agents receive reply_to_id,
has_reply_context, and the untrusted reply-target block exactly like
Discord replies (mirrors #90263). Reply targets without a persisted
transcript id keep the inline-quote fallback.

Co-Authored-By: Claude Fable 5 <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui gateway Gateway runtime size: M labels Jul 18, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Codex review: needs maintainer review before merge. Reviewed July 18, 2026, 4:05 PM ET / 20:05 UTC.

Summary
Adds Control UI reply selection that persists a reply target id, sends it through the Gateway protocol, and hydrates agent-visible reply context from the selected session transcript message.

PR surface: Source +216, Tests +218, Docs +1, Other +6. Total +441 across 14 files.

Reproducibility: not applicable. This PR adds a new reply workflow rather than reporting broken existing behavior; focused tests describe the intended source path, but they are not after-fix runtime proof.

Review metrics: 1 noteworthy metric.

  • New durable reply contract: 1 optional Gateway parameter and 1 persisted outbox field added. The reply target now survives queued sends and crosses the public Control UI-to-Gateway boundary, so the upgrade and product contract should be deliberate.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted after-fix proof of right-click Reply, message submission or replay, and the hydrated reply context observed by the agent.
  • Obtain explicit maintainer confirmation that the additive chat.send.replyToId and agent-visible reply-context contract should ship.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body reports tests and static checks but contains no redacted after-fix WebChat-to-Gateway run showing reply selection, send or replay, and hydrated agent-visible context; add a recording, terminal/live output, or runtime logs with private data redacted. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A redacted Web UI chat transcript can directly demonstrate the missing real behavior proof for reply selection and resulting reply-aware agent context. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis web UI chat proof: verify and capture a redacted WebChat reply-to flow showing the selected message and the resulting reply-aware agent response.

Risk before merge

  • [P1] Merging creates an additive public Gateway request field and durable queued-send metadata, so a maintainer should explicitly accept the intended Control UI and agent-prompt contract before it becomes a supported surface.
  • [P1] The PR has tests and static validation but no redacted after-fix real run demonstrating WebChat reply selection, send or offline replay, and the resulting hydrated agent-visible context.

Maintainer options:

  1. Decide the mitigation before merge
    Accept one additive replyToId contract only if a maintainer confirms the WebChat product direction and a redacted real run proves the selected transcript target reaches the agent through the shared reply-context path.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] A maintainer must accept the new public reply contract, and the contributor must provide real behavior proof that an automated repair lane cannot substitute.

Maintainer decision needed

  • Question: Should chat.send.replyToId become a supported Gateway/Control UI capability that exposes the selected WebChat transcript message as agent reply context?
  • Rationale: This is a new user-visible Control UI workflow and additive Gateway protocol surface; tests establish the intended mechanics, but maintainer intent is needed to accept the permanent public contract and agent-visible semantics.
  • Likely owner: fuller-stack-dev — They introduced the merged shared reply-context model and have recently maintained the corresponding Gateway and WebChat integration path.
  • Options:
    • Accept the shared reply contract (recommended): Approve the additive WebChat reply workflow after real behavior proof confirms selection, send or replay, and hydrated agent context.
    • Defer the protocol surface: Keep the existing inline-quote behavior until a maintainer-sponsored design specifies the desired WebChat reply contract.

Security
Cleared: No concrete security or supply-chain regression is evident in the reviewed patch: it adds no dependency, privilege, or external execution path and keeps hydrated reply text on the existing untrusted reply-context route.

Review details

Best possible solution:

Accept one additive replyToId contract only if a maintainer confirms the WebChat product direction and a redacted real run proves the selected transcript target reaches the agent through the shared reply-context path.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR adds a new reply workflow rather than reporting broken existing behavior; focused tests describe the intended source path, but they are not after-fix runtime proof.

Is this the best way to solve the issue?

Unclear pending maintainer direction: reusing the established channel-agnostic reply envelope is the narrowest implementation path, but the new public Gateway and agent-context contract still needs explicit acceptance.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1626a1696c60.

Label changes

Label justifications:

  • P2: This is a bounded Control UI workflow improvement with a new protocol surface, not an urgent regression or release-blocking failure.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body reports tests and static checks but contains no redacted after-fix WebChat-to-Gateway run showing reply selection, send or replay, and hydrated agent-visible context; add a recording, terminal/live output, or runtime logs with private data redacted. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +216, Tests +218, Docs +1, Other +6. Total +441 across 14 files.

View PR surface stats
Area Files Added Removed Net
Source 10 222 6 +216
Tests 2 218 0 +218
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 1 6 0 +6
Total 14 447 6 +441

What I checked:

  • Control UI request path: The branch carries a persisted transcript message id through the queued send and includes it as optional replyToId on chat.send, retaining the inline-quote path when no persisted target exists. (ui/src/pages/chat/chat-send.ts:283, 93e4837c24b1)
  • Gateway hydration boundary: The Gateway resolves the reply target from the session transcript and applies only channel-agnostic ReplyToId, ReplyToBody, and ReplyToSender fields before inbound dispatch. (src/gateway/server-methods/chat-send-reply-context.ts:1, 93e4837c24b1)
  • Existing shared reply-context precedent: The merged Discord implementation established the shared reply-context envelope this PR reuses; this PR is a WebChat integration rather than a competing agent-facing reply model. (src/gateway/server-methods/chat.ts:1203, c84e52192063)
  • Automated validation status: The supplied check data shows focused boundary, protocol, prompt, security, and several QA checks succeeded, while broader build, UI, lint, and compact lanes were still running at review time; this does not replace real behavior proof. (93e4837c24b1)

Likely related people:

  • fuller-stack-dev: Authored the merged Discord reply-context implementation that this PR explicitly mirrors and authored the follow-up commits refining this branch's dispatch ordering and reply-body visibility behavior. (role: introduced and recently maintained the shared reply-context behavior; confidence: high; commits: c84e52192063, 15bb513b65b2, 105dd699212a; files: src/gateway/server-methods/chat.ts, src/gateway/server-methods/chat-send-reply-context.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (4 earlier review cycles)
  • reviewed 2026-07-18T16:10:07.355Z sha cd48cc3 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-18T17:28:00.903Z sha 15bb513 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-18T17:36:47.635Z sha d89b96a :: needs maintainer review before merge. :: none
  • reviewed 2026-07-18T19:32:53.557Z sha 105dd69 :: needs maintainer review before merge. :: none

@fuller-stack-dev fuller-stack-dev self-assigned this Jul 18, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 18, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 18, 2026
@fuller-stack-dev
fuller-stack-dev merged commit b88646c into main Jul 18, 2026
117 checks passed
@fuller-stack-dev
fuller-stack-dev deleted the feat/webchat-reply-context branch July 18, 2026 21:58
@fuller-stack-dev

Copy link
Copy Markdown
Member

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 19, 2026
…aw#110791)

* feat(webchat): reply-to a message with hydrated reply context

Control UI replies now carry the target transcript id as replyToId on
chat.send. The Gateway resolves the replied-to message from session
history and hydrates the channel-agnostic ReplyToId/ReplyToBody/
ReplyToSender envelope fields, so agents receive reply_to_id,
has_reply_context, and the untrusted reply-target block exactly like
Discord replies (mirrors openclaw#90263). Reply targets without a persisted
transcript id keep the inline-quote fallback.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(webchat): keep non-reply chat.send dispatch ordering and satisfy CI gates

* docs(webchat): match reply-context doc to webchat conversation-info policy

* fix(webchat): hydrate reply bodies from display-visible content only

---------

Co-authored-by: openclaw-clawsweeper[bot] <openclaw-clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: fuller-stack-dev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui docs Improvements or additions to documentation gateway Gateway runtime P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant