Skip to content

fix(ui): preserve graphemes in provider icons#109509

Merged
steipete merged 6 commits into
openclaw:mainfrom
Leon-SK668:fix/control-ui-provider-icon-grapheme-20260717
Jul 21, 2026
Merged

fix(ui): preserve graphemes in provider icons#109509
steipete merged 6 commits into
openclaw:mainfrom
Leon-SK668:fix/control-ui-provider-icon-grapheme-20260717

Conversation

@Leon-SK668

@Leon-SK668 Leon-SK668 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Custom model-provider ids can contain arbitrary Unicode, but the Control UI fallback icon used charAt(0). Emoji-leading ids therefore rendered a lone UTF-16 surrogate; flags, joined emoji, and combining characters were also split.

Why This Change Was Made

Moves the existing plugin-monogram grapheme splitter into a shared Control UI helper and reuses it for provider fallback icons. Known provider asset resolution and empty-id fallback behavior remain unchanged.

User Impact

Custom providers now show one complete visible grapheme in Chat, Model Providers, and Memory Import instead of a malformed fallback icon.

Evidence

  • Added real Lit row-rendering coverage for emoji, flag, ZWJ, and combining-mark provider ids.
  • Existing plugin tests continue to cover the shared helper, including the Intl.Segmenter-unavailable fallback.
  • node scripts/run-vitest.mjs ui/src/pages/model-providers/view.test.ts ui/src/pages/plugins/view.test.ts: 30 tests passed.
  • Targeted oxfmt --check, oxlint, and git diff --check passed.
  • Fresh pre-commit autoreview: clean, 0.90 correctness confidence.
  • Verified the provider-id contract only trims/lowercases config keys and does not restrict them to ASCII.
  • No exact live open duplicate found. Full changed-gate execution is delegated to PR CI because the local Blacksmith Testbox CLI path is unavailable.

Exact-head browser proof

  • Exact tested PR head: 5cc979c86f6b3389c69430171c5ede0c5ca4ecdf (workflow commit 1882d21fb385dd3d46a932a9b1f89db4f50c5a68). The secretless GitHub-hosted Chromium run passed 3/3 focused Model Providers E2E tests in Chrome for Testing 149.0.7827.55.
  • DOM assertions verified the complete fallback graphemes S, 🧭, 🇺🇸, 👩‍💻, and , including Lit template whitespace normalization.
  • The top and bottom 1280x1000 screenshots were visually inspected together: all five badges are visible with no replacement character, overlap, or clipping. The two WebM recordings (2.08s and 2.76s) are non-empty, decodable, and show the Unicode scroll plus the credential/probe flow.
  • Artifact 8451788545, pr109509-exact-head-chromium-5cc979c86f6b, is 1,039,329 bytes and contains four PNGs plus two WebMs; retained through 2026-08-03. Key Unicode captures: 03-unicode-fallback-icons.png (133,229 bytes) and 04-unicode-fallback-icons-bottom.png (109,383 bytes).

@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. labels Jul 17, 2026
@clawsweeper

clawsweeper Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 20, 2026, 2:35 AM ET / 06:35 UTC.

Summary
The branch adds a shared Control UI grapheme helper, uses it for custom provider fallback icons and plugin monograms, and adds Unicode-focused unit and Chromium E2E coverage.

PR surface: Source +1, Tests +84. Total +85 across 6 files.

Reproducibility: yes. from source: the pre-change provider fallback uses charAt(0), which can return a lone UTF-16 surrogate for an emoji-leading identifier; the branch’s focused browser cases exercise the affected UI path.

Review metrics: none identified.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

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

Next step before merge

  • [P2] No mechanical repair is indicated; a maintainer should review the current merge result and required checks before landing this proof-complete PR.

Security
Cleared: The six-file UI and test-only diff adds no dependency, workflow, permission, secret, packaging, or external-code-execution surface.

Review details

Best possible solution:

Keep one shared, grapheme-aware Control UI helper and land the focused regression coverage after the maintainer confirms the current clean merge result.

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

Yes, from source: the pre-change provider fallback uses charAt(0), which can return a lone UTF-16 surrogate for an emoji-leading identifier; the branch’s focused browser cases exercise the affected UI path.

Is this the best way to solve the issue?

Yes. Reusing a shared grapheme helper is the narrowest maintainable fix because provider fallbacks and plugin monograms share the Unicode-cluster invariant, and the branch covers both the normal Intl.Segmenter path and its fallback.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6304a47762cc.

Label changes

Label changes:

  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.

Label justifications:

  • P2: This is a bounded Control UI rendering bug that affects custom Unicode provider identifiers without threatening runtime availability or persisted state.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (linked_artifact): Exact-head Chromium E2E evidence includes DOM assertions plus screenshots and recordings that directly show intact Unicode fallback icons in the Model Providers UI.
  • proof: sufficient: Contributor real behavior proof is sufficient. Exact-head Chromium E2E evidence includes DOM assertions plus screenshots and recordings that directly show intact Unicode fallback icons in the Model Providers UI.
Evidence reviewed

PR surface:

Source +1, Tests +84. Total +85 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 3 23 22 +1
Tests 3 84 0 +84
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 107 22 +85

What I checked:

  • Current sibling behavior: Current main’s plugin monogram implementation trims and splits words, then uses slice(0, 2) or [0] before uppercasing, so it does not preserve grapheme clusters; the PR centralizes segmentation for that sibling and provider fallback path. (ui/src/pages/plugins/presentation.ts:1840, 6304a47762cc)
  • Provider fallback fix: The PR replaces the provider fallback’s charAt(0) path with takeGraphemes(provider.trim().toUpperCase(), 1), retaining the existing empty-provider ? fallback and known provider asset resolution. (ui/src/components/provider-icon.ts:121, 5cc979c86f6b)
  • Regression coverage: The branch adds Lit rendering assertions and Chromium E2E cases for an emoji, flag, ZWJ sequence, combining mark, and an uppercase-expanding character; the latter confirms grapheme limiting occurs after case conversion. (ui/src/e2e/model-providers.e2e.test.ts:186, 5cc979c86f6b)
  • Exact-head behavior proof: The PR body identifies a successful secretless Chromium run at the exact head, with DOM assertions and visual artifacts showing the five fallback badges without malformed surrogate output. (ui/src/e2e/model-providers.e2e.test.ts:186, 5cc979c86f6b)
  • Repository policy fit: The repository policy requires reviewing changed modules, sibling surfaces, tests, current behavior, and real evidence for user-visible changes; this review covered the provider path, the sibling plugin monogram path, focused tests, proof, and CI context. (AGENTS.md:2, 6304a47762cc)

Likely related people:

  • BunsDev: The PR timeline shows an explicit mention shortly after the proof-complete review transition, making this the only concrete non-author routing signal available from the supplied history; current-main file provenance could not be retrieved from the read-only execution environment. (role: review participant; confidence: low; files: ui/src/components/provider-icon.ts, ui/src/pages/plugins/presentation.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 (9 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-17T03:17:46.085Z sha 74e460d :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T03:58:06.883Z sha 74e460d :: needs maintainer review before merge. :: none
  • reviewed 2026-07-20T03:05:23.643Z sha 4363581 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-20T03:41:04.346Z sha ab004b0 :: needs real behavior proof before merge. :: [P2] Limit graphemes after case conversion
  • reviewed 2026-07-20T04:46:01.339Z sha f5b4d3c :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-20T05:14:52.451Z sha 2113c63 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-20T05:30:49.188Z sha 5cc979c :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-20T05:51:53.691Z sha 5cc979c :: needs maintainer review before merge. :: none

@Leon-SK668

Copy link
Copy Markdown
Contributor Author

Added exact-head real-browser proof to the PR body. Google Chrome rendered the emoji, flag, ZWJ, and combining-mark fallback badges intact in the actual Model Providers view; DOM grapheme, surrogate, per-badge pixel, full-page pixel, page-error, and console-error checks all passed. A full-page screenshot and 3.88-second recording were captured and visually inspected.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. and removed 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. labels Jul 17, 2026
@Leon-SK668
Leon-SK668 force-pushed the fix/control-ui-provider-icon-grapheme-20260717 branch from 74e460d to 4363581 Compare July 20, 2026 03:01
@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 proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 20, 2026
@Leon-SK668
Leon-SK668 force-pushed the fix/control-ui-provider-icon-grapheme-20260717 branch from 4363581 to ab004b0 Compare July 20, 2026 03:36
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 20, 2026
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 20, 2026
@steipete steipete self-assigned this Jul 21, 2026
@steipete
steipete force-pushed the fix/control-ui-provider-icon-grapheme-20260717 branch from 5cc979c to c526472 Compare July 21, 2026 03:01
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(ui): preserve graphemes in provider icons 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.

@steipete
steipete merged commit 9ad0a97 into openclaw:main Jul 21, 2026
91 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

vincentkoc added a commit that referenced this pull request Jul 21, 2026
* origin/main: (24 commits)
  fix(agents): keep compaction on live session model (#95713)
  fix(plugin-sdk): guard provider catalog live URL parsing against malformed responses (#109986)
  chore(cli): drop dead classifiers and single-use wrappers left by fallback removal (#112191)
  feat(ui): expand the lobster pet's random universe (#112073)
  chore(ci): audit dependency fingerprint exports (#112190)
  fix(ui): preserve graphemes in provider icons (#109509)
  fix(ui): align settings search with navigation rows (#112172)
  fix(agents): allow configless gateway rebind to activate standalone owner (#111841)
  fix(secrets): register secret targets for installed-origin plugins (#104347)
  improve(ui): show real machine identity in the place picker (#112162)
  fix: webChat scrollback history is too limited — older assistant replies and tool outputs disappear when scrolling… (#104250)
  test(ui): run DOM-free suites in Node (#112031)
  feat(nodes): make computer.act eligibility capability-based for desktop nodes (#112107)
  fix(apps): harden mobile gateway and watch state
  fix(ci): restore Z.AI API Platform validation (#112171)
  fix(ui): prevent Logs controls from overlapping (#112170)
  fix #95291: message tool fails to deliver files/images on Feishu (400 volc-dcdn / write ECONNRESET) while same Lark SDK upload succeeds standalone (#95514)
  refactor(cli)!: remove automatic gateway→embedded fallback from openclaw agent (#112074)
  refactor: move provider transports into packages/ai behind a typed host port (#111669)
  fix(anthropic): complete transcript reverse-scan windows across short reads (#109431)
  ...
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 22, 2026
* fix(ui): preserve graphemes in provider icons

* fix(ui): clamp uppercase provider icon graphemes

* test(ui): cover provider icon graphemes in Chromium

* test(ui): ignore fallback icon template whitespace

* test(ui): capture complete fallback icon proof

* test(ui): align provider probe E2E scope

Co-authored-by: Leon-SK668 <[email protected]>

---------

Co-authored-by: Leon-SK668 <[email protected]>
Co-authored-by: Peter Steinberger <[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 P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants