Skip to content

feat(macos): visible-markdown copy, full-message reader, and independent reasoning/tool toggles#110276

Merged
steipete merged 3 commits into
mainfrom
claude/macos-chat-message-reader
Jul 18, 2026
Merged

feat(macos): visible-markdown copy, full-message reader, and independent reasoning/tool toggles#110276
steipete merged 3 commits into
mainfrom
claude/macos-chat-message-reader

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Three message-level gaps versus the web chat: copying an assistant message grabs raw primary text (including markup the user never saw), messages truncated by bounded history cannot be opened in full, and reasoning + tool activity share a single all-or-nothing toggle while the web controls them independently.

Why This Change Was Made

Round 3 of native/web chat alignment, scoped to the message layer:

  • Assistant copy now uses the visible-Markdown parser (thinking excluded), matching what the transcript renders.
  • History decoding retains the gateway's __openclaw.id / __openclaw.truncated metadata (wire contract verified at src/gateway/session-utils.fs.ts:792 and the ...(truncated)... marker at chat-display-projection.ts:80); truncated messages gain an "Open Full Message" action that fetches chat.message.get (schema verified in packages/gateway-protocol/src/schema/logs-chat.ts) into a selectable, scrollable reader with loading/unavailable/failure states. The transport method is additive with a nil default, so other hosts compile unchanged.
  • The single trace flag becomes independent "Show reasoning" and "Show tool activity" options (two menu checkmarks, persisted); the old UserDefaults key migrates to both toggles, and the old shared-API parameter still sets both for compatibility.

User Impact

Copy produces exactly what you read; long responses clipped by history limits are one click from their full content; and reasoning vs tool visibility are now separate choices, both remembered — matching the web chat.

Evidence

  • Shared package: build + 897 tests pass; focused new coverage 7/7 (metadata decode, copy behavior, message.get encoding, display-option migration).
  • macOS: release build passes; focused mapping/smoke 18/18. Full suite ran 1337 tests with two failures in untouched GatewayProcessManagerTests (subsystem not modified by this PR; under separate investigation).
  • pnpm format:swift, pnpm lint:swift, i18n sync idempotent; new strings translated across all 21 locales; Apple/Android catalogs regenerated.
  • Structured review: clean, no actionable findings.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: ios App: ios app: macos App: macos size: XL maintainer Maintainer-authored PR labels Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68da399ea3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

self.phase = .failed(String(localized: "The full message is no longer available."))
return
}
let markdown = ChatMessageVisibleText.visibleText(in: message)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve enabled trace content in full-message reader

When a truncated assistant row is visible only because Show Reasoning or Show Tool Activity is enabled, the new reader still calls ChatMessageVisibleText.visibleText, which always strips thinking and non-text tool content. In that scenario the user can choose Open Full Message from a visible truncated reasoning/tool row, but the sheet either omits the content they were viewing or reports “no readable text”; the reader needs to render with the same display options used by the transcript bubble.

Useful? React with 👍 / 👎.

@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. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 17, 2026, 10:28 PM ET / July 18, 2026, 02:28 UTC.

Summary
The branch updates native chat to copy assistant-visible Markdown, open truncated transcript messages in a full reader, and persist independent reasoning and tool-activity display toggles.

PR surface: Docs 0, Other +2454. Total +2454 across 36 files.

Reproducibility: yes. from source: an iOS host using the default requestFullMessage implementation can show the new truncated-message action but receives nil; the full-reader mismatch is also directly implied when enabled reasoning or tool content is opened.

Review metrics: 1 noteworthy metric.

  • Persisted trace preferences: 2 added, 1 legacy key migrated. These stored preferences alter upgrade behavior and must preserve the prior shared setting while allowing independent controls.

Stored data model
Persistent data-model change detected: vector/embedding metadata: apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMessageVisibleTextTests.swift. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P1] Implement retrieval for iOS or hide the action behind a transport capability.
  • Pass the active reasoning/tool display options into the reader and cover the enabled-content case.
  • [P1] Add redacted macOS and iOS runtime proof showing copy output, successful full-message retrieval, and independent persisted toggles.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body reports builds and focused tests, but no inspectable after-fix native run, recording, terminal output, or redacted runtime artifact demonstrates visible-text copy, a successful full-message retrieval, and independently persisted toggles. Add redacted evidence; updating the PR body should trigger re-review, or a maintainer can comment @clawsweeper re-review. 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.

Risk before merge

  • [P1] Merging the shared truncation UI without an iOS transport implementation or an explicit capability gate gives iOS users an action that deterministically fails.
  • [P1] The added persisted display-option compatibility surface needs both host parity and a demonstrated upgrade path before merge.

Maintainer options:

  1. Repair shared-host support before merge (recommended)
    Preserve the active display options in the reader and ensure every host that can show the action can fetch the message, with focused regression coverage.
  2. Narrow the action to macOS
    If iOS retrieval is intentionally deferred, add an explicit capability gate so iOS never offers a reader action that must fail.

Next step before merge

  • [P1] The protected maintainer label, feature-scope choice, and missing contributor-supplied behavior proof require human handling rather than an automated repair lane.

Maintainer decision needed

  • Question: Should full-message retrieval be implemented for iOS in this shared native-chat change, or should the new action be explicitly limited to macOS until iOS supports the gateway request?
  • Rationale: The current shared implementation exposes the feature beyond the only transport that implements retrieval, and choosing parity versus an intentionally macOS-only scope is a maintained product boundary.
  • Likely owner: steipete — The supplied branch history shows this contributor owns the proposed shared/macOS/iOS integration changes.
  • Options:
    • Implement native-host parity (recommended): Add the iOS gateway implementation and retain the action only where each transport can retrieve the full message.
    • Make the feature macOS-only for now: Add an explicit transport capability and hide the action from iOS until its retrieval path is implemented.

Security
Cleared: The reviewed diff changes native Swift UI, message decoding, gateway request mapping, tests, docs, and generated localization catalogs without adding dependency, CI, secret, permission, or artifact-execution paths.

Review findings

  • [P1] Gate full-message reading on transport support — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatTransport.swift:332-334
  • [P2] Preserve enabled trace content in the full-message reader — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift:16-20
Review details

Best possible solution:

Carry the active display options into the full-message reader, then either implement chat.message.get for every native gateway transport that exposes truncated messages or gate the action behind an explicit capability; add redacted native runtime proof for copy, successful reader retrieval, and independently persisted toggles.

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

Yes, from source: an iOS host using the default requestFullMessage implementation can show the new truncated-message action but receives nil; the full-reader mismatch is also directly implied when enabled reasoning or tool content is opened.

Is this the best way to solve the issue?

No: the current shared reader is not the best fix until it carries transcript display state and the capability boundary is made explicit across macOS and iOS.

Full review comments:

  • [P1] Gate full-message reading on transport support — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatTransport.swift:332-334
    The new shared truncation metadata lets iOS present “Open Full Message,” but its transport inherits the new default that always returns nil. Implement chat.message.get for iOS or add an explicit capability so the failing action is never shown.
    Confidence: 0.97
  • [P2] Preserve enabled trace content in the full-message reader — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift:16-20
    The reader does not receive the active reasoning/tool display options, so opening a truncated row that is visible only because one of those options is enabled omits that visible content or reports no readable text. Carry the same display state into the reader.
    Confidence: 0.94

Overall correctness: patch is incorrect
Overall confidence: 0.94

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against 1bd6280f8549.

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: The defects are user-visible native-chat regressions with a bounded host-specific blast radius.
  • merge-risk: 🚨 compatibility: A shared native-chat API and persisted preference migration can change behavior for existing macOS and iOS users.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • 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 builds and focused tests, but no inspectable after-fix native run, recording, terminal output, or redacted runtime artifact demonstrates visible-text copy, a successful full-message retrieval, and independently persisted toggles. Add redacted evidence; updating the PR body should trigger re-review, or a maintainer can comment @clawsweeper re-review. 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:

Docs 0, Other +2454. Total +2454 across 36 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 1 3 3 0
Config 0 0 0 0
Generated 0 0 0 0
Other 35 3159 705 +2454
Total 36 3162 708 +2454

What I checked:

  • iOS fallback remains actionable but unavailable: The new OpenClawChatTransport.requestFullMessage default returns nil; the PR adds truncation metadata in the shared model, while the review discussion identifies that IOSGatewayChatTransport does not override this method. A truncated iOS row can therefore expose “Open Full Message” and always end in the unavailable state. (apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatTransport.swift:332, 4ddebb3be80f)
  • Prior full-reader finding remains applicable: The reader still accepts only a message and Markdown variant, not the active display options; its loaded path therefore cannot preserve reasoning or tool content that the transcript intentionally shows. The earlier review discussion describes this exact user-visible mismatch, and the later head commit only adjusts an iOS render-smoke call site. (apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift:16, 4ddebb3be80f)
  • Preference migration is upgrade-sensitive: The branch adds two persisted UserDefaults keys and migrates the legacy shared trace preference into both values. The intended migration is covered by a focused test, but the resulting shared display-option surface must remain behaviorally consistent across native hosts. (apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift:21, 4ddebb3be80f)
  • Existing review continuity: The prior ClawSweeper review at commit 68da399ea35bbf4e036af2c3b0d3a77a1b3dd9c6 raised the trace-content reader defect. The current head 4ddebb3be80f5f456144793bb393dc272095e792 includes i18n regeneration and an iOS smoke-test API adoption after the main feature commit, not a repair of the reader behavior. (apps/ios/Tests/SwiftUIRenderSmokeTests.swift:208, 4ddebb3be80f)

Likely related people:

  • steipete: The supplied commit history attributes all three branch commits covering the shared chat surface, macOS transport, iOS smoke call sites, and localization update to this contributor; no current-main feature-history attribution was available from the read-only environment. (role: native chat feature contributor; confidence: medium; commits: 783e9e12ad57, ca0472787734, 4ddebb3be80f; files: apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift, apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift, apps/ios/Tests/SwiftUIRenderSmokeTests.swift)
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 (1 earlier review cycle)
  • reviewed 2026-07-18T01:25:33.976Z sha 68da399 :: needs real behavior proof before merge. :: [P2] Preserve enabled trace content in the full-message reader

@steipete
steipete force-pushed the claude/macos-chat-message-reader branch from 68da399 to ca04727 Compare July 18, 2026 01:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca04727877

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1045 to +1048
if role == "assistant",
message.isTruncated,
let messageID = message.transcriptMessageID?.trimmingCharacters(in: .whitespacesAndNewlines),
!messageID.isEmpty

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate full-message action on transport support

When this shared view is used by iOS or any host that does not override OpenClawChatTransport.requestFullMessage, decoded __openclaw metadata now makes truncated assistant rows satisfy this condition, but the protocol default still returns nil and IOSGatewayChatTransport has no override. Those users will see an actionable “Open Full Message” item that always opens the failure state even though the gateway can serve chat.message.get; hide the action unless the transport supports it or implement the new method for the other gateway transports.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: feat(macos): visible-markdown copy, full-message reader, and independent reasoning/tool toggles This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@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
@steipete
steipete merged commit 9dec7ac into main Jul 18, 2026
102 of 104 checks passed
@steipete
steipete deleted the claude/macos-chat-message-reader branch July 18, 2026 03:05
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 18, 2026
…ent reasoning/tool toggles (openclaw#110276)

* feat(clients): copy visible markdown, full-message reader for truncated messages, and independent reasoning/tool toggles

* chore(i18n): translate new reader and trace strings and regenerate catalogs

* test(ios): adopt reader display-options API in render smoke tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: ios App: ios app: macos App: macos docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL 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