From 4f79a275a8f7e104e9ca3bf31ebba6e7a5e6da69 Mon Sep 17 00:00:00 2001 From: suzmii Date: Thu, 3 Sep 2026 13:39:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=8E=E5=8C=96=20AGC=20=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E8=AE=BE=E7=BD=AE=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 收敛账号与角色协作展示文案 增加账号状态检测动画和状态卡片样式 将流式输出与联网检索整理为单列 更新设置页回归测试与配置护栏 --- .../scripts/check-config.mjs | 3 +- .../runtime-config/RuntimeConfigDialog.tsx | 104 ++++++++++-------- apps/ai-game-creator-shell/src/styles.css | 63 +++++++++++ .../appSurface/runtime-settings.suite.ts | 92 +++++++++++++--- 4 files changed, 201 insertions(+), 61 deletions(-) diff --git a/apps/ai-game-creator-shell/scripts/check-config.mjs b/apps/ai-game-creator-shell/scripts/check-config.mjs index 5e76d0a32..53a7f7c07 100644 --- a/apps/ai-game-creator-shell/scripts/check-config.mjs +++ b/apps/ai-game-creator-shell/scripts/check-config.mjs @@ -1757,7 +1757,8 @@ for (const snippet of [ "'read_game_creator_app_config'", "'write_game_creator_app_config'", 'aria-label="运行时配置"', - '官方账号服务(固定)', + '智能创作', + '账号状态', 'External Editor Base URL', 'External Editor API Key', 'runtime_config.save', diff --git a/apps/ai-game-creator-shell/src/features/runtime-config/RuntimeConfigDialog.tsx b/apps/ai-game-creator-shell/src/features/runtime-config/RuntimeConfigDialog.tsx index 8cd344cea..e315ba8ac 100644 --- a/apps/ai-game-creator-shell/src/features/runtime-config/RuntimeConfigDialog.tsx +++ b/apps/ai-game-creator-shell/src/features/runtime-config/RuntimeConfigDialog.tsx @@ -124,7 +124,7 @@ const runtimeSettingsSections = [ { id: 'agents', label: 'Agent 分工', - description: '查看各角色运行状态', + description: '角色协作状态', icon: Bot, }, { @@ -258,6 +258,7 @@ export function RuntimeConfigDialog({ const [runtimeConfigBusy, setRuntimeConfigBusy] = useState(false); const [effectiveLlmConfigStatus, setEffectiveLlmConfigStatus] = useState(llmConfigStatus); + const [llmConfigChecking, setLlmConfigChecking] = useState(false); const [activeSection, setActiveSection] = useState('general'); const [clientExtensions, setClientExtensions] = useState< @@ -502,6 +503,7 @@ export function RuntimeConfigDialog({ ); setRuntimeConfigDraft(config); setRuntimeConfigStatus(`已读取:${result.path}`); + setLlmConfigChecking(true); try { const status = await invoke( 'check_game_creator_llm_config', @@ -510,6 +512,8 @@ export function RuntimeConfigDialog({ } catch { // Older test fixtures and non-Tauri previews may not expose the // diagnostic command; the config read itself remains usable. + } finally { + setLlmConfigChecking(false); } onLog?.('runtime_config.read'); } catch (error) { @@ -730,13 +734,7 @@ export function RuntimeConfigDialog({ <>
工作方式 - 陶泥儿智能创作(固定) - 需求将由官方智能服务执行 -
-
- 智能服务 - 官方账号服务(固定) - 登录后自动使用当前账号权限。 + 智能创作
{(() => { const credential = formatAccountCredentialState( @@ -744,17 +742,28 @@ export function RuntimeConfigDialog({ ); return (
- 账号权限 - {credential.label} - - {credential.tone === 'success' - ? '当前账号已具备智能创作权限。' - : '请返回登录页完成登录或重新登录;普通用户无需填写任何智能服务凭据。'} - + 账号状态 + + {llmConfigChecking ? ( + <> +
); })()} @@ -780,34 +789,36 @@ export function RuntimeConfigDialog({ ))} - - +
+ + +
) : null} @@ -912,9 +923,8 @@ export function RuntimeConfigDialog({ ) : null} {activeSection === 'agents' ? (
- 角色服务 - 所有角色使用统一账号服务 - 普通用户无需配置服务连接信息。 + 角色协作 + 已启用
) : null} {activeSection === 'connections' ? ( diff --git a/apps/ai-game-creator-shell/src/styles.css b/apps/ai-game-creator-shell/src/styles.css index e4281b392..ef59e7073 100644 --- a/apps/ai-game-creator-shell/src/styles.css +++ b/apps/ai-game-creator-shell/src/styles.css @@ -3901,6 +3901,69 @@ h2 { align-content: start; } +.runtime-settings-readonly-field, +.runtime-settings-option-stack > label { + display: grid; + gap: 7px; + min-width: 0; + padding: 13px; + border: 1px solid var(--platform-subpanel-border); + border-radius: 12px; + background: linear-gradient( + 145deg, + var(--runtime-settings-subpanel-fill), + color-mix(in srgb, var(--runtime-settings-subpanel-fill) 78%, #f0e7dc) + ); + color: var(--platform-text-base); +} + +.runtime-settings-readonly-field > span, +.runtime-settings-option-stack > label { + font-size: 11px; +} + +.runtime-settings-readonly-field > span { + color: var(--platform-text-soft); +} + +.runtime-settings-readonly-field > strong { + display: inline-flex; + align-items: center; + gap: 6px; + min-height: 20px; + color: var(--platform-text-strong); + font-size: 13px; + font-weight: 800; +} + +.runtime-settings-readonly-field[data-tone='success'] { + border-color: color-mix( + in srgb, + var(--platform-success-border) 70%, + transparent + ); + background: linear-gradient(145deg, #fbfffc, #f1faf2); +} + +.runtime-settings-readonly-field[data-checking='true'] { + border-color: var(--platform-nav-active-border); + background: linear-gradient(145deg, #fffdf9, #f8f1e7); +} + +.runtime-settings-account-state[data-checking='true'] > strong { + color: var(--platform-accent); +} + +.runtime-settings-readonly-field .is-spinning { + animation: runtime-settings-spin 0.9s linear infinite; +} + +.runtime-settings-option-stack { + display: grid; + gap: 10px; + min-width: 0; +} + .runtime-settings-fields > label { padding: 13px; border: 1px solid var(--platform-subpanel-border); diff --git a/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts index ece3e4022..a35eb7162 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts @@ -255,6 +255,69 @@ export function registerAgentStatusDerivationTests() { } export function registerRuntimeSettingsTests() { + it('shows a checking animation while account status is being verified', async () => { + let resolveAccountCheck!: (status: unknown) => void; + const accountCheck = new Promise((resolve) => { + resolveAccountCheck = resolve; + }); + const invoke = vi.fn((command: string) => { + if (command === 'read_game_creator_app_config') { + return Promise.resolve({ + path: '/home/test/AppData/game-creator.config.json', + config: { + agentMode: 'codex_app_server', + llm: { + apiKey: '', + baseUrl: '', + model: '', + apiKind: 'openai_responses', + reasoningEffort: 'high', + stream: true, + webSearchEnabled: true, + contextWindowTokens: 128000, + autoCompactTokenLimit: 64000, + toolOutputTokenLimit: 12000, + requestTimeoutMs: 180000, + maxRetries: 2, + retryBackoffMs: 500, + }, + agentLlm: {}, + editorApi: { baseUrl: '', apiKey: '' }, + }, + }); + } + if (command === 'check_game_creator_llm_config') { + return accountCheck; + } + throw new Error(`unexpected invoke ${command}`); + }); + window.__TAURI__ = { core: { invoke } }; + renderLauncherAt('/?launcher'); + + fireEvent.click(screen.getByRole('button', { name: '配置' })); + const accountState = await screen.findByTestId( + 'runtime-settings-account-credential-state', + ); + await waitFor(() => { + expect(accountState.getAttribute('data-checking')).toBe('true'); + }); + expect(accountState.querySelector('.is-spinning')).not.toBeNull(); + expect(screen.getByText('正在检测')).not.toBeNull(); + + await act(async () => { + resolveAccountCheck({ + accountCredentialState: 'ready', + configured: true, + }); + }); + + await waitFor(() => { + expect(accountState.getAttribute('data-checking')).toBe('false'); + expect(accountState.querySelector('.is-spinning')).toBeNull(); + }); + expect(screen.getByText('账号权限已就绪')).not.toBeNull(); + }); + it('distinguishes loading the client extension list from an empty list', async () => { let resolveExtensions!: (items: unknown[]) => void; const extensionsRead = new Promise((resolve) => { @@ -404,9 +467,11 @@ export function registerRuntimeSettingsTests() { renderLauncherAt('/?launcher'); fireEvent.click(screen.getByRole('button', { name: '配置' })); - expect(await screen.findByText('陶泥儿智能创作(固定)')).not.toBeNull(); + expect(await screen.findByText('智能创作')).not.toBeNull(); expect(screen.queryByLabelText('Agent 模式')).toBeNull(); - expect(screen.getByText('官方账号服务(固定)')).not.toBeNull(); + expect(screen.getByText('账号状态')).not.toBeNull(); + expect(screen.queryByText('官方账号服务(固定)')).toBeNull(); + expect(screen.queryByText('普通用户无需填写任何智能服务凭据。')).toBeNull(); expect( screen.queryByText(/router\.genarrative\.world|gpt-5\.6-sol/), ).toBeNull(); @@ -477,7 +542,7 @@ export function registerRuntimeSettingsTests() { renderLauncherAt('/?launcher'); fireEvent.click(screen.getByRole('button', { name: '配置' })); - expect(await screen.findByText('陶泥儿智能创作(固定)')).not.toBeNull(); + expect(await screen.findByText('智能创作')).not.toBeNull(); expect(screen.queryByLabelText('Agent 模式')).toBeNull(); fireEvent.click(screen.getByRole('button', { name: '保存' })); @@ -531,7 +596,7 @@ export function registerRuntimeSettingsTests() { fireEvent.click(screen.getByRole('button', { name: '配置' })); const dialog = await screen.findByRole('dialog', { name: '运行时配置' }); - expect(screen.getByText('官方账号服务(固定)')).not.toBeNull(); + expect(screen.getByText('账号状态')).not.toBeNull(); expect( screen.queryByText(/router\.genarrative\.world|gpt-5\.6-sol/), ).toBeNull(); @@ -822,7 +887,7 @@ export function registerPublishedRuntimeSettingsTests() { fireEvent.click(screen.getByRole('button', { name: '配置' })); - expect(await screen.findByText('官方账号服务(固定)')).not.toBeNull(); + expect(await screen.findByText('账号状态')).not.toBeNull(); expect( screen.queryByText(/router\.genarrative\.world|gpt-5\.6-sol/), ).toBeNull(); @@ -847,7 +912,8 @@ export function registerPublishedRuntimeSettingsTests() { expect(screen.queryByLabelText('External Editor Base URL')).toBeNull(); expect(screen.queryByLabelText('External Editor API Key')).toBeNull(); fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ })); - expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull(); + expect(screen.getByText('已启用')).not.toBeNull(); + expect(screen.queryByText('所有角色使用统一账号服务')).toBeNull(); fireEvent.click(screen.getByRole('button', { name: /常用设置/ })); expect(screen.getByLabelText('联网检索')).toHaveProperty('checked', false); fireEvent.click(screen.getByRole('button', { name: /高级参数/ })); @@ -864,7 +930,7 @@ export function registerPublishedRuntimeSettingsTests() { '12000', ); fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ })); - expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull(); + expect(screen.getByText('已启用')).not.toBeNull(); fireEvent.click(screen.getByRole('button', { name: /常用设置/ })); expect(screen.getByLabelText('推理档')).toHaveProperty('value', 'medium'); @@ -895,7 +961,7 @@ export function registerPublishedRuntimeSettingsTests() { target: { value: '800' }, }); fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ })); - expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull(); + expect(screen.getByText('已启用')).not.toBeNull(); fireEvent.click(screen.getByRole('button', { name: /连接与工具/ })); expect(screen.queryByLabelText('External Editor Base URL')).toBeNull(); expect(screen.queryByLabelText('External Editor API Key')).toBeNull(); @@ -943,7 +1009,7 @@ export function registerPublishedRuntimeSettingsTests() { fireEvent.click(screen.getByRole('button', { name: /常用设置/ })); expect(screen.getByLabelText('联网检索')).toHaveProperty('checked', true); fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ })); - expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull(); + expect(screen.getByText('已启用')).not.toBeNull(); expect(screen.getByLabelText('聊天').textContent).not.toContain( 'unit-new-secret-value', ); @@ -983,9 +1049,9 @@ export function registerPublishedRuntimeSettingsTests() { expect(screen.getByText('已恢复默认配置,保存后生效')).not.toBeNull(); fireEvent.click(screen.getByRole('button', { name: /常用设置/ })); - expect(screen.getByText('陶泥儿智能创作(固定)')).not.toBeNull(); + expect(screen.getByText('智能创作')).not.toBeNull(); expect(screen.queryByLabelText('Agent 模式')).toBeNull(); - expect(screen.getByText('官方账号服务(固定)')).not.toBeNull(); + expect(screen.getByText('账号状态')).not.toBeNull(); expect( screen.queryByText(/router\.genarrative\.world|gpt-5\.6-sol/), ).toBeNull(); @@ -995,7 +1061,7 @@ export function registerPublishedRuntimeSettingsTests() { expect(screen.getByLabelText('推理档')).toHaveProperty('value', 'max'); expect(screen.getByLabelText('联网检索')).toHaveProperty('checked', true); fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ })); - expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull(); + expect(screen.getByText('已启用')).not.toBeNull(); fireEvent.click(screen.getByRole('button', { name: /高级参数/ })); expect(screen.getByLabelText('上下文窗口 tokens')).toHaveProperty( 'value', @@ -1086,7 +1152,7 @@ export function registerPublishedRuntimeSettingsTests() { renderAppAt('/'); fireEvent.click(screen.getByRole('button', { name: '配置' })); - expect(await screen.findByText('官方账号服务(固定)')).not.toBeNull(); + expect(await screen.findByText('账号状态')).not.toBeNull(); expect(screen.queryByLabelText('LLM Provider')).toBeNull(); expect(screen.queryByLabelText('LLM API Key')).toBeNull(); expect(screen.queryByLabelText('LLM Base URL')).toBeNull();