Skip to content

service-ai: complete I18nLabelSchema migration for Setup nav labels#1127

Merged
xuyushun441-sys merged 2 commits into
mainfrom
copilot/fix-i18n-object-format
Apr 14, 2026
Merged

service-ai: complete I18nLabelSchema migration for Setup nav labels#1127
xuyushun441-sys merged 2 commits into
mainfrom
copilot/fix-i18n-object-format

Conversation

Copilot AI commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

AIServicePlugin was still contributing Setup App navigation labels using the deprecated { key, defaultValue } i18n object shape, while I18nLabelSchema now requires plain strings. This aligns service-ai with the post-#1054 label contract and with already-migrated plugins.

  • Plugin migration (service-ai)

    • Updated packages/services/service-ai/src/plugin.ts setup navigation contributions:
      • nav_ai_conversations label → 'Conversations'
      • nav_ai_messages label → 'Messages'
    • Removed the last deprecated label-object usage in setup navigation contributions under services/plugins scope.
  • Focused regression coverage

    • Added an integration assertion in packages/services/service-ai/src/__tests__/ai-service.test.ts to verify setupNav.contribute() receives plain string labels for AI nav items.
  • Changelog

    • Added an Unreleased > Fixed entry in CHANGELOG.md documenting the service-ai migration completion for deprecated i18n label objects.
// before
{ id: 'nav_ai_conversations', label: { key: 'setup.nav.ai_conversations', defaultValue: 'Conversations' } }
{ id: 'nav_ai_messages', label: { key: 'setup.nav.ai_messages', defaultValue: 'Messages' } }

// after
{ id: 'nav_ai_conversations', label: 'Conversations' }
{ id: 'nav_ai_messages', label: 'Messages' }
Original prompt

Problem

In packages/services/service-ai/src/plugin.ts (lines 234-235), the AIServicePlugin contributes navigation items to the Setup App using the old i18n object format { key, defaultValue } instead of plain strings:

// Current (WRONG):
{ id: 'nav_ai_conversations', type: 'object', label: { key: 'setup.nav.ai_conversations', defaultValue: 'Conversations' }, objectName: 'conversations', icon: 'message-square', order: 10 },
{ id: 'nav_ai_messages', type: 'object', label: { key: 'setup.nav.ai_messages', defaultValue: 'Messages' }, objectName: 'messages', icon: 'messages-square', order: 20 },

This violates the I18nLabelSchema change documented in CHANGELOG.md (related to #1054):

i18n: I18nLabelSchema now accepts string only — The previous string | I18nObject union type has been replaced with z.string(). i18n translation keys will be auto-generated by the framework at registration time; developers only need to provide the default-language string value.

Migration: Replace any label: { key: '...', defaultValue: 'X' } with label: 'X'.

All other plugins (plugin-auth, plugin-security, plugin-audit) were already migrated — service-ai was missed.

Required Fix

In packages/services/service-ai/src/plugin.ts, change the setupNav.contribute() call:

// Before:
{ id: 'nav_ai_conversations', type: 'object', label: { key: 'setup.nav.ai_conversations', defaultValue: 'Conversations' }, objectName: 'conversations', icon: 'message-square', order: 10 },
{ id: 'nav_ai_messages', type: 'object', label: { key: 'setup.nav.ai_messages', defaultValue: 'Messages' }, objectName: 'messages', icon: 'messages-square', order: 20 },

// After:
{ id: 'nav_ai_conversations', type: 'object', label: 'Conversations', objectName: 'conversations', icon: 'message-square', order: 10 },
{ id: 'nav_ai_messages', type: 'object', label: 'Messages', objectName: 'messages', icon: 'messages-square', order: 20 },

Additional Tasks

  1. Search the entire codebase for any other remaining instances of label: { key: pattern in navigation contributions or setupNav calls that may have been missed during the i18n: label 应为纯字符串,key 由框架自动生成 #1054 migration.
  2. Run tests to ensure nothing breaks (pnpm test or the relevant test suite for service-ai and related packages).
  3. Update CHANGELOG.md — Add an entry under a new ## Unreleased section (or the latest section) documenting the fix:
    • Category: Fixed
    • Description: service-ai: Fix navigation item labels using deprecated i18n object format — Replaced { key, defaultValue } i18n objects with plain string labels in AIServicePlugin's Setup App navigation contributions, completing the I18nLabelSchema migration from i18n: label 应为纯字符串,key 由框架自动生成 #1054.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: 这是本项目的问题嘛 https://github.com/objectstack-ai/objectui/tasks/f8914881-2ceb-488c-812a-2bfb4734546a

问题源头在上游 ⚠️

@objectstack/plugin-auth 的源代码中贡献的是纯字符串标签
但在运行时,这些标签被转换成了 i18n 对象格式
这是 @objectstack framework 内部的转换逻辑问题

Assistant: Now I can see the issue clearly. The @objectstack/plugin-auth contributes plain string labels (e.g., label: 'Users'), but somewhere in the framework runtime, these are being wrongly transformed into i18n object format (e.g., { key: '...', defaultValue: 'Users' }). Let me dig deeper into the runtime transformation logic.

Assistant: Now I can see the key issue. Let me look at the service-ai plugin more closely since it's still using the old i18n object format, and also check for any other plugins that might not have been updated:

Assistant: 我已经完整地分析了这个问题。以下是我的发现:

问题分析

你提到的问题是:@objectstack/plugin-auth 贡献的导航项使用纯字符串 label,但在运行时被显示为 i18n 对象格式 { key, defaultValue }

根本原因定位

经过代码追踪,问题源头不在 @objectstack/plugin-auth,而在 @objectstack/service-ai

  1. @objectstack/plugin-auth (packages/plugins/plugin-auth/src/auth-plugin.ts 第 120-128 行) — ✅ 已正确使用纯字符串标签

    label: 'Users'       // ✅ 纯字符串
    label: 'Organizations' // ✅ 纯字符串
    label: 'Teams'        // ✅ 纯字符串
  2. @objectstack/plugin-security / @objectstack/plugin-audit — ✅ 也已正确使用纯字符串。

  3. ⚠️ @objectstack/service-ai (packages/services/service-ai/src/plugin.ts 第 234-235 行) — ❌ 仍在使用旧的 i18n 对象格式

    label: { key: 'setup.nav.ai_conversations', defaultValue: 'Conversations' }  // ❌ 应为纯字符串
    label: { key: 'setup.nav.ai_messages', defaultValue: 'Messages' }            // ❌ 应为纯字符串

这违反了 CHANGELOG 中记录的 I18nLabelSchema 变更(string | I18nObjectstring only),该变更已在 #1054 中完成。

为什么 Studio 侧边栏能容忍这个问题

Studio 的 app-sidebar.tsx(第 142-147 行)有一个 resolveLabel() 防御函数来兼容两种格式:

function resolveLabel(val: unknown): string {
  if (typeof val === 'string') return val;
  if (val && typeof val === 'obj...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

@vercel

vercel Bot commented Apr 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Ready Ready Preview, Comment Apr 14, 2026 3:16am
spec Ready Ready Preview, Comment Apr 14, 2026 3:16am

Request Review

Copilot AI changed the title [WIP] Fix i18n object format in AIServicePlugin service-ai: complete I18nLabelSchema migration for Setup nav labels Apr 14, 2026
Copilot AI requested a review from hotlong April 14, 2026 03:13
@xuyushun441-sys
xuyushun441-sys marked this pull request as ready for review April 14, 2026 03:21
@xuyushun441-sys
xuyushun441-sys merged commit 66e901b into main Apr 14, 2026
3 checks passed
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.

3 participants