8000 fix(artifact-tab): decode text artifacts as UTF-8 by moneebarif1 · Pull Request #478 · google/adk-web · GitHub
[go: up one dir, main page]

Skip to content

fix(artifact-tab): decode text artifacts as UTF-8 - #478

Merged
copybara-service[bot] merged 2 commits into
google:mainfrom
moneebarif1:fix/artifact-text-utf8-decode
Sep 24, 2026
Merged

copybara-service[bot] merged 2 commits into
google:mainfrom
moneebarif1:fix/artifact-text-utf8-decode

Conversation

@moneebarif1
Copy link
Copy Markdown
Contributor

Summary

Fixes #452.

Text artifacts containing non-ASCII characters (Japanese, Arabic, emoji, …) rendered as mojibake in the Artifacts tab preview — e.g. こんにちは showed as ã?"ã‚"ã?«ã?¡ã?¯.

Root cause

getTextContent() in artifact-tab.component.ts decoded the base64 payload with a bare atob(). atob() returns a "binary string" where each character is a single byte, so multibyte UTF-8 sequences are misinterpreted as Latin-1 (ISO-8859-1).

Fix

Decode the base64 into raw bytes and run them through TextDecoder('utf-8'):

const bytes = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
return new TextDecoder('utf-8').decode(bytes);

This is the correct inverse of the UTF-8-aware encode path. I used TextDecoder rather than the decodeURIComponent(escape(...)) idiom suggested in the issue, since escape/unescape are deprecated.

Testing

Added regression tests to artifact-tab.component.spec.ts covering multibyte (こんにちは 🌙 مرحبا), ASCII, and empty-input cases. All component tests pass:

Chrome Headless: Executed 4 of 4 SUCCESS

getTextContent() decoded base64 with a bare atob(), which produces a
Latin-1 binary string. Multibyte UTF-8 sequences were therefore
misinterpreted, so non-ASCII text artifacts (e.g. Japanese, Arabic,
emoji) rendered as mojibake in the Artifacts tab preview.

Decode the base64 into raw bytes and run them through TextDecoder('utf-8')
so multibyte content round-trips correctly. Uses TextDecoder instead of
the deprecated escape()/unescape() pair.

Adds regression tests for multibyte, ASCII, and empty-input cases.

Fixes google#452
@wyf7107
wyf7107 commented Aug 18, 2026
Copy link
Copy Markdown
Collaborator

hi, thanks for the PR, do you mind sync to HEAD and update this PR?

@moneebarif1
Copy link
Copy Markdown
Contributor Author

Done — synced the branch with the latest main (merged upstream HEAD, no conflicts). The PR is up to date now.

@moneebarif1
moneebarif1 requested a review from wyf7107 August 19, 2026 10:01
@copybara-service
copybara-service Bot merged commit 894c04b into google:main Sep 24, 2026
6 checks passed
magiccao pushed a commit to magiccao/adk-web that referenced this pull request Oct 22, 2026
getTextContent() in ContentBubbleComponent returned atob(base64)
directly, rendering the UTF-8 bytes of multibyte text artifacts as
Latin-1 characters in the inline chat preview (e.g. CJK text shows as
mojibake). The same bug was fixed for the Artifacts tab in google#478;
this applies the identical TextDecoder-based decode to content-bubble
and adds unit tests mirroring the artifact-tab spec.

Fixes google#551
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text artifact preview renders garbled characters for non-ASCII (multibyte) content

2 participants

0