fix(desktop): 修复 10 个 agent 对话测试发现的缺陷
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- BUG-001+002 P0: 模型选择器合并 SaaS 可用模型列表 - BUG-003 P1: 修复 relay 错误消息重复显示 - BUG-005 P1: 设置页面显示实际连接模式和地址 - BUG-006 P2: 统一 UI 语言为中文 - BUG-009 P3: 错误时隐藏建议按钮 - BUG-010 P3: 密码切换按钮添加 aria-label Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { useArtifactStore } from '../store/chat/artifactStore';
|
||||
import { useConnectionStore } from '../store/connectionStore';
|
||||
import { useAgentStore } from '../store/agentStore';
|
||||
import { useConfigStore } from '../store/configStore';
|
||||
import { useSaaSStore } from '../store/saasStore';
|
||||
import { type UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { safeListenEvent } from '../lib/safe-tauri';
|
||||
import { Paperclip, SquarePen, ArrowUp, MessageSquare, Download, X, FileText, Image as ImageIcon, Search } from 'lucide-react';
|
||||
@@ -63,7 +64,21 @@ export function ChatArea() {
|
||||
const connectionState = useConnectionStore((s) => s.connectionState);
|
||||
const { activeClassroom, classroomOpen, closeClassroom, generating, progressPercent, progressActivity, error: classroomError, clearError: clearClassroomError } = useClassroomStore();
|
||||
const clones = useAgentStore((s) => s.clones);
|
||||
const models = useConfigStore((s) => s.models);
|
||||
const configModels = useConfigStore((s) => s.models);
|
||||
const saasModels = useSaaSStore((s) => s.availableModels);
|
||||
const isLoggedIn = useSaaSStore((s) => s.isLoggedIn);
|
||||
|
||||
// Merge models: SaaS available models take priority when logged in
|
||||
const models = useMemo(() => {
|
||||
if (isLoggedIn && saasModels.length > 0) {
|
||||
return saasModels.map(m => ({
|
||||
id: m.alias || m.id,
|
||||
name: m.alias || m.id,
|
||||
provider: m.provider_id,
|
||||
}));
|
||||
}
|
||||
return configModels;
|
||||
}, [isLoggedIn, saasModels, configModels]);
|
||||
|
||||
const [input, setInput] = useState('');
|
||||
const [pendingFiles, setPendingFiles] = useState<File[]>([]);
|
||||
@@ -418,8 +433,8 @@ export function ChatArea() {
|
||||
) : (
|
||||
<EmptyState
|
||||
icon={<MessageSquare className="w-8 h-8" />}
|
||||
title="Welcome to ZCLAW"
|
||||
description={connected ? 'Send a message to start the conversation.' : 'Please connect to Gateway first in Settings.'}
|
||||
title="欢迎使用 ZCLAW"
|
||||
description={connected ? '发送消息开始对话。' : '请先在设置中连接 Gateway。'}
|
||||
/>
|
||||
)}
|
||||
</motion.div>
|
||||
@@ -457,7 +472,7 @@ export function ChatArea() {
|
||||
<div className="p-4 bg-white dark:bg-gray-900">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
{/* Suggestion chips */}
|
||||
{!isStreaming && suggestions.length > 0 && (
|
||||
{!isStreaming && suggestions.length > 0 && !messages.some(m => m.error) && (
|
||||
<SuggestionChips
|
||||
suggestions={suggestions}
|
||||
onSelect={(text) => { setInput(text); textareaRef.current?.focus(); }}
|
||||
|
||||
@@ -440,6 +440,7 @@ export function LoginPage() {
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
className="absolute right-3 top-1/2 -translate-y-1/2 text-white/30 hover:text-white/60 cursor-pointer"
|
||||
tabIndex={-1}
|
||||
aria-label={showPassword ? '隐藏密码' : '显示密码'}
|
||||
>
|
||||
{showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import { useConnectionStore } from '../../store/connectionStore';
|
||||
import { useConfigStore } from '../../store/configStore';
|
||||
import { useConversationStore } from '../../store/chat/conversationStore';
|
||||
import { useSaaSStore } from '../../store/saasStore';
|
||||
import { getStoredGatewayToken, setStoredGatewayToken } from '../../lib/gateway-client';
|
||||
import { silentErrorHandler } from '../../lib/error-utils';
|
||||
|
||||
@@ -22,6 +23,7 @@ export function General() {
|
||||
|
||||
const connected = connectionState === 'connected';
|
||||
const connecting = connectionState === 'connecting' || connectionState === 'reconnecting';
|
||||
const saasUrl = useSaaSStore((s) => s.saasUrl);
|
||||
|
||||
// 同步主题设置
|
||||
useEffect(() => {
|
||||
@@ -97,7 +99,9 @@ export function General() {
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-700">地址</span>
|
||||
<span className="text-sm text-gray-500 font-mono">ws://127.0.0.1:50051</span>
|
||||
<span className="text-sm text-gray-500 font-mono">
|
||||
{gatewayVersion === 'saas-relay' && saasUrl ? saasUrl : 'ws://127.0.0.1:50051'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-700">Token</span>
|
||||
|
||||
@@ -100,8 +100,8 @@ export function EmptyConversations({ action, className, size }: PrebuiltEmptySta
|
||||
return (
|
||||
<EmptyState
|
||||
icon={<Inbox className="w-8 h-8" />}
|
||||
title="No conversations"
|
||||
description="Your conversation history will appear here."
|
||||
title="暂无对话"
|
||||
description="你的对话历史将显示在这里。"
|
||||
action={action}
|
||||
className={className}
|
||||
size={size}
|
||||
@@ -177,8 +177,8 @@ export function EmptyAgents({ action, className, size }: PrebuiltEmptyStateProps
|
||||
* Empty state for welcome screen.
|
||||
*/
|
||||
export function WelcomeEmptyState({
|
||||
title = "Welcome to ZCLAW",
|
||||
description = "Send a message to start the conversation.",
|
||||
title = "欢迎使用 ZCLAW",
|
||||
description = "发送消息开始对话。",
|
||||
connected = true,
|
||||
action,
|
||||
className,
|
||||
|
||||
@@ -410,7 +410,7 @@ export const useStreamStore = create<StreamState>()(
|
||||
_chat?.updateMessages(msgs =>
|
||||
msgs.map(m =>
|
||||
m.id === assistantId
|
||||
? { ...m, content: `⚠️ ${error}`, streaming: false, error }
|
||||
? { ...m, content: '', streaming: false, error }
|
||||
: m.role === 'user' && m.optimistic && m.timestamp.getTime() >= streamStartTime
|
||||
? { ...m, optimistic: false }
|
||||
: m
|
||||
|
||||
Reference in New Issue
Block a user