Skip to content

feat(core): localize the agent chat interface - #2655

Open
tillkrueger02 wants to merge 12 commits into
BuilderIO:mainfrom
tillkrueger02:codex/localize-core-agent-chat
Open

feat(core): localize the agent chat interface#2655
tillkrueger02 wants to merge 12 commits into
BuilderIO:mainfrom
tillkrueger02:codex/localize-core-agent-chat

Conversation

@tillkrueger02

@tillkrueger02 tillkrueger02 commented Aug 5, 2026

Copy link
Copy Markdown

Summary

  • Add built-in Agent Chat translations for all 11 supported locales.
  • Localize Core chat surfaces, sharing controls, error states, composer controls, voice mode, and Context X-Ray.
  • Add RTL-aware layout behavior and locale-aware date, number, duration, and table formatting.
  • Preserve app-level catalog overrides while providing complete Core-owned fallback translations.

Why

The Agent Chat currently contains Core- and Toolkit-owned English strings that app catalogs cannot reliably translate.

This change gives the shared Agent Chat interface its own built-in catalogs, while allowing applications to continue overriding individual messages. It also ensures Arabic renders with the appropriate RTL direction and logical layout utilities.

Changes

  • Add lazy-loaded Core Agent Chat catalogs for:
    • Arabic
    • Simplified Chinese
    • Traditional Chinese
    • English
    • French
    • German
    • Hindi
    • Japanese
    • Korean
    • Brazilian Portuguese
    • Spanish
  • Merge built-in Core messages with application catalogs without overwriting app-provided translations.
  • Preserve previously published agentPanel and contextXray catalog overrides through compatibility aliases.
  • Localize:
    • Agent Chat navigation, tabs, empty states, status messages, and recovery controls
    • Composer commands, modes, attachments, model selection, and voice controls
    • Tool-call displays and structured data widgets
    • Context Meter and Context X-Ray
    • Sharing and feedback controls
    • Known Core-generated error messages and recovery actions
  • Use logical CSS utilities and RTL-specific transforms for bidirectional layouts.
  • Add locale-aware formatting for dates, numbers, durations, counts, and table values.
  • Extend the i18n guard to cover the complete Core chat and Toolkit composer surfaces.
  • Add a changeset for @agent-native/core and @agent-native/toolkit.
  • Address review feedback by including the default English framework fallback in every locale bundle and mapping legacy app overrides back to agentChat.* while preserving explicit new-path overrides.
  • Use localized delegated-agent labels and selected-locale formatting for elapsed durations, inline error durations, step-limit counts, and pasted-text counts.
  • Merge the current upstream main into the feature branch without force-pushing.

Tests

  • Post-merge Core regression tests: 5 files, 253 tests passed
  • Toolkit composer conflict tests: 2 files, 24 tests passed
  • Full Toolkit source suite: 47 files, 376 tests passed
  • Full Core suite before the latest upstream merge: 783 files passed; 10,640 tests passed; 1 skipped; 3 known local baseline failures
  • Standalone Chat smoke passed after the latest upstream merge: scaffold → install → dev server → auto-login → /agent → Chat surface
  • Core and Toolkit package typechecks passed after conflict resolution
  • All 44 repository guards passed
  • pnpm fmt:check passed across 14,595 files
  • git diff --check passed
  • German UI manually verified
  • Arabic RTL UI manually verified
  • Full workspace typecheck after the latest upstream merge reports unrelated errors in packages/docs and several templates; affected Core and Toolkit package typechecks are green

Known Baseline Failures

The full Core test suite is not completely green in the local macOS environment. It completed with 10,640 passing tests, 1 skipped test, and 3 failures outside the changed localization surfaces:

  • src/cli/clean.spec.ts
    • The symlink cleanup test treats the temporary symlink path as a directory on this macOS filesystem.
  • src/jobs/actions/actions.spec.ts
    • Expects UTC, while the local environment produces Europe/Berlin.
  • src/triggers/actions/actions.spec.ts
    • Expects UTC, while the local environment produces Europe/Berlin.

The two timezone-dependent suites pass completely with TZ=UTC (12/12 tests). The affected Core and Toolkit localization suites are fully green.

After merging the latest upstream main, the local full-workspace typecheck also reports errors in unchanged documentation and template packages. The affected Core and Toolkit package typechecks pass; the fresh GitHub CI run is authoritative for the newly merged upstream package build order.

Screenshots

German Agent Chat

german-chat-final

Arabic Agent Chat with RTL layout

arabic-chat-final

Risk / Rollback

  • Risk: The shared ShareButton is used outside Agent Chat, so its built-in translations also improve other Core consumers.
  • Risk: Visible composer-mode prefixes are sent in the selected interface language. Internal operational context and agent instructions remain in English.
  • Risk: Catalog structure, placeholders, fallback behavior, German, and Arabic were verified, but every translation has not been reviewed by a native speaker.
  • Mitigation: English remains the source fallback, application catalogs retain override priority, and catalog guards verify key and placeholder consistency.
  • Rollback plan: Revert the localization commits, review follow-up, and associated changeset. No database migration or persisted-data rollback is required.

Checklist

  • No secrets or credentials added
  • No database migrations
  • App-level translation overrides remain supported
  • RTL behavior manually verified
  • Changeset added
  • Backwards compatibility aliases added for existing catalog keys
  • Screenshots uploaded

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Visual recap — skipped

The visual recap job did not run for this pull request. This is informational only and does not block the PR.

Recap skipped for 57fe722: external fork PR requires a maintainer to apply the recap label to the current head SHA.

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

Copy link
Copy Markdown

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: a8b5115ccf

ℹ️ 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 841 to +845
? isRunning
? `Asking ${agentName}...`
? t("agentChat.tool.askingAgent", { agent: agentName })
: isAgentError
? `Error asking ${agentName}`
: `Asked ${agentName}`
? t("agentChat.tool.askingAgentFailed", { agent: agentName })
: t("agentChat.tool.askedAgent", { agent: agentName })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use localized labels for agent-call cards

When a non-English locale renders an agent:* or call-agent tool, these agentChat.tool.* translations are computed but never shown because the branch below returns AgentCallCell; that component still reads agentPanel.delegatedAgent.*, which only falls back to the English default catalog. The delegated-agent card therefore continues to show English statuses like “Asking/Asked/Error asking” even though the new locale catalogs contain translated tool.askingAgent labels, so pass the localized label into the card or switch the card to these keys.

Useful? React with 👍 / 👎.

builder-io-integration[bot]

This comment was marked as outdated.

@steve8708

Copy link
Copy Markdown
Contributor

great catch @tillkrueger02! some feedback above and merge conflicts that would be great to resolve

…gent-chat

# Conflicts:
#	packages/core/src/client/AssistantChat.tsx
#	packages/core/src/client/chat/run-recovery.tsx
#	packages/toolkit/src/composer/TiptapComposer.tsx

@builder-io-integration builder-io-integration 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.

Builder reviewed your changes and found 2 potential issues 🟡

Review Details

Incremental Code Review Summary

The latest commit addresses the two prior review findings: every locale bundle now composes the default English fallback, and legacy app overrides are normalized into the modern agentChat namespace with explicit modern values taking precedence. The previously reported duration/count formatting gaps were also corrected, and focused regression coverage was added. The overall catalog and formatting architecture remains sound, and this remains a standard-risk shared UI change.

New findings

  • 🟡 MEDIUM — Voice mode still reads agentPanel.voiceMode.*, so explicit app overrides under the modern agentChat.voiceMode.* namespace are ignored in the voice controller. This makes voice-mode override precedence inconsistent with the rest of the migration.
  • 🟡 MEDIUM — Core Context X-Ray still supplies its title and governance labels from legacy contextXray.* keys, so modern agentChat.contextXray.* overrides do not apply consistently to those labels.
  • 🟢 LOW — The selected-context pill still formats its count with the browser locale rather than the selected application locale.
  • 🟢 LOW — Message timestamps join separately formatted date and time strings with a hard-coded English comma, which can produce incorrect punctuation/order and bidi behavior in some locales.

🧪 Browser testing: Will run after this review (PR touches UI code)

hideChat: t("agentPanel.voiceMode.hideChat"),
endVoiceMode: t("agentPanel.voiceMode.end"),
voiceSettings: t("agentPanel.voiceMode.voiceSettings"),
entryButtonLabel: t("agentPanel.voiceMode.entryButtonLabel", {

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.

🟡 Read voice copy from the modern agentChat namespace

The voice controller still reads its labels from agentPanel.voiceMode.*, while the new override normalization makes agentChat.voiceMode.* the modern namespace and gives explicit modern values precedence. An app override such as agentChat.voiceMode.entryButtonLabel is therefore ignored here because the built-in legacy alias remains at agentPanel.voiceMode.*. Read from agentChat.voiceMode.* throughout voiceCopy so legacy overrides continue to normalize forward and modern overrides work consistently.

Additional Info
Found by 2 of 4 parallel reviewers.

Fix in Builder

onPin={onPin}
onEvict={onEvict}
onRestore={onRestore}
translate={t}

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.

🟡 Use modern agentChat keys for Context X-Ray labels

This wrapper still looks up titleLabel, systemOrderedLabel, and governanceLabels through legacy contextXray.* keys. Modern app overrides under agentChat.contextXray.* are normalized only forward into the modern namespace, so these labels keep the built-in legacy values while the rest of the panel uses modern keys. Change these lookups to agentChat.contextXray.* while retaining the defaults.

Additional Info
Found by 2 of 4 parallel reviewers.

Fix in Builder

…gent-chat

# Conflicts:
#	packages/core/src/client/chat/run-recovery.spec.tsx
#	packages/core/src/client/chat/run-recovery.tsx
builder-io-integration[bot]

This comment was marked as outdated.

@tillkrueger02

Copy link
Copy Markdown
Author

great catch @tillkrueger02! some feedback above and merge conflicts that would be great to resolve

@steve8708 please let me know if anything else needs to be done for the PR. Btw love the project!

…gent-chat

# Conflicts:
#	packages/toolkit/src/composer/MentionPopover.tsx
#	packages/toolkit/src/composer/TiptapComposer.tsx

@builder-io-integration builder-io-integration 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.

Builder reviewed your changes and has a few items to flag 🟡

Review Details

Incremental Code Review Summary

The latest commit was reviewed by four parallel agents with the two existing voice-mode and Context X-Ray findings explicitly excluded because they remain open and unchanged. The current delta otherwise preserves the catalog fallback, compatibility normalization, RTL, and formatting architecture; no new high- or medium-severity issues were confirmed.

One low-severity localization defect remains in the new known-error mapping: the builder_auth_error normalization emits a message containing (free tier available), but the exact-string translation map omits that phrase, so this common authentication recovery message remains English in non-English locales. A previously observed selected-context count formatting gap also remains low severity.

🧪 Browser testing: Will run after this review (PR touches UI code)

…gent-chat

# Conflicts:
#	packages/core/src/client/chat/message-components.tsx
#	packages/core/src/client/chat/tool-call-display.tsx
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.

2 participants