style(assistant): compact model picker in header

This commit is contained in:
huanghuoguoguo
2026-09-16 22:37:02 +08:00
parent 0be53c6ef4
commit 38471d5df1
5 changed files with 55 additions and 44 deletions
@@ -205,34 +205,16 @@ function AssistantPanel({ storageKey }: { storageKey: string }) {
<header className="flex items-center gap-2 border-b p-3"> <header className="flex items-center gap-2 border-b p-3">
<MessageCircle className="size-5 text-primary" /> <MessageCircle className="size-5 text-primary" />
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<h2 className="font-semibold">{t('assistant.title')}</h2> <h2 className="truncate font-semibold">{t('assistant.title')}</h2>
<p className="truncate text-xs text-muted-foreground"> <p className="truncate text-xs text-muted-foreground">
{t('assistant.subtitle')} {t('assistant.subtitle')}
</p> </p>
</div> </div>
<Button
variant="ghost"
size="icon"
disabled={busy}
onClick={reset}
aria-label={t('assistant.newChat')}
>
<Plus />
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => setOpen(false)}
aria-label={t('assistant.close')}
>
<X />
</Button>
</header>
{open && ( {open && (
<div className="space-y-1 border-b px-3 py-2"> <div
<span className="text-xs text-muted-foreground"> className="w-28 min-w-0 shrink-0"
{t('assistant.modelHint')} title={t('assistant.modelHint')}
</span> >
<DynamicFormItemComponent <DynamicFormItemComponent
config={{ config={{
id: 'assistant-model', id: 'assistant-model',
@@ -249,12 +231,34 @@ function AssistantPanel({ storageKey }: { storageKey: string }) {
onBlur: () => {}, onBlur: () => {},
ref: () => {}, ref: () => {},
disabled: disabled:
busy || (!!conversation && conversation.status !== 'ready'), busy ||
(!!conversation && conversation.status !== 'ready'),
}} }}
requiredModelAbility="func_call" requiredModelAbility="func_call"
compactModelSelector
/> />
</div> </div>
)} )}
<Button
variant="ghost"
size="icon"
className="size-7 shrink-0"
disabled={busy}
onClick={reset}
aria-label={t('assistant.newChat')}
>
<Plus />
</Button>
<Button
variant="ghost"
size="icon"
className="size-7 shrink-0"
onClick={() => setOpen(false)}
aria-label={t('assistant.close')}
>
<X />
</Button>
</header>
<div <div
className="flex-1 space-y-3 overflow-y-auto p-4" className="flex-1 space-y-3 overflow-y-auto p-4"
aria-live="polite" aria-live="polite"
@@ -89,6 +89,7 @@ export default function DynamicFormItemComponent({
setFormValue, setFormValue,
systemContext, systemContext,
requiredModelAbility, requiredModelAbility,
compactModelSelector = false,
}: { }: {
config: IDynamicFormItemSchema; config: IDynamicFormItemSchema;
field: ControllerRenderProps<any, any>; field: ControllerRenderProps<any, any>;
@@ -97,6 +98,7 @@ export default function DynamicFormItemComponent({
setFormValue?: (name: string, value: unknown) => void; setFormValue?: (name: string, value: unknown) => void;
systemContext?: Record<string, unknown>; systemContext?: Record<string, unknown>;
requiredModelAbility?: string; requiredModelAbility?: string;
compactModelSelector?: boolean;
}) { }) {
const [llmModels, setLlmModels] = useState<LLMModel[]>([]); const [llmModels, setLlmModels] = useState<LLMModel[]>([]);
const [embeddingModels, setEmbeddingModels] = useState<EmbeddingModel[]>([]); const [embeddingModels, setEmbeddingModels] = useState<EmbeddingModel[]>([]);
@@ -468,7 +470,14 @@ export default function DynamicFormItemComponent({
onValueChange={field.onChange} onValueChange={field.onChange}
disabled={field.disabled} disabled={field.disabled}
> >
<SelectTrigger className="min-w-0 bg-[#ffffff] dark:bg-[#2a2a2e]"> <SelectTrigger
aria-label={t('models.selectModel')}
className={
compactModelSelector
? 'w-full min-w-0 gap-1 border-0 bg-transparent px-1 text-xs text-muted-foreground shadow-none hover:bg-muted data-[size=default]:h-7 [&_[data-slot=select-value]_svg]:hidden'
: 'min-w-0 bg-[#ffffff] dark:bg-[#2a2a2e]'
}
>
<SelectValue placeholder={t('models.selectModel')} /> <SelectValue placeholder={t('models.selectModel')} />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
@@ -605,7 +614,7 @@ export default function DynamicFormItemComponent({
type="button" type="button"
variant="ghost" variant="ghost"
size="icon" size="icon"
className="h-9 w-9 shrink-0" className={compactModelSelector ? 'hidden' : 'h-9 w-9 shrink-0'}
onClick={() => { onClick={() => {
setSettingsSection('models'); setSettingsSection('models');
setModelsDialogOpen(true); setModelsDialogOpen(true);
+4 -5
View File
@@ -1,7 +1,6 @@
const enUS = { const enUS = {
assistant: { assistant: {
modelHint: modelHint: 'Switch assistant model for your next message',
'Assistant model · Space recommendation by default; changes apply to your next message',
details: 'View raw data', details: 'View raw data',
found: 'Found {{count}} items', found: 'Found {{count}} items',
completed: 'Completed', completed: 'Completed',
@@ -29,8 +28,8 @@ const enUS = {
knowledge_bases: 'Find knowledge bases', knowledge_bases: 'Find knowledge bases',
knowledge_engines: 'Find knowledge engines', knowledge_engines: 'Find knowledge engines',
}, },
title: 'Workspace assistant · Experimental', title: 'Workspace assistant',
subtitle: 'Build with your Space model', subtitle: 'Build and manage your apps',
newChat: 'New conversation', newChat: 'New conversation',
close: 'Close', close: 'Close',
welcome: welcome:
@@ -43,7 +42,7 @@ const enUS = {
decline: 'Decline', decline: 'Decline',
working: 'Working…', working: 'Working…',
modelUnavailable: modelUnavailable:
'The Space model is unavailable. Check your Space account and model access in Settings, then start a new conversation.', 'Model unavailable. Check its configuration and access, then start a new conversation.',
error: error:
'This turn did not complete. Check the resource results before starting a new conversation; changes are not retried automatically.', 'This turn did not complete. Check the resource results before starting a new conversation; changes are not retried automatically.',
running: running:
+4 -5
View File
@@ -1,7 +1,6 @@
const jaJP = { const jaJP = {
assistant: { assistant: {
modelHint: modelHint: '次のメッセージからモデルを切り替え',
'アシスタントモデル · 既定は Space 推奨。変更は次のメッセージから適用',
details: '元のデータを見る', details: '元のデータを見る',
found: '{{count}} 件見つかりました', found: '{{count}} 件見つかりました',
completed: '完了', completed: '完了',
@@ -29,8 +28,8 @@ const jaJP = {
knowledge_bases: 'ナレッジベース検索', knowledge_bases: 'ナレッジベース検索',
knowledge_engines: 'エンジン検索', knowledge_engines: 'エンジン検索',
}, },
title: 'ワークスペースアシスタント · 実験版', title: 'ワークスペースアシスタント',
subtitle: 'Space モデルでアプリを構築', subtitle: 'アプリを構築・管理',
newChat: '新しい会話', newChat: '新しい会話',
close: '閉じる', close: '閉じる',
welcome: welcome:
@@ -43,7 +42,7 @@ const jaJP = {
decline: '拒否', decline: '拒否',
working: '処理中…', working: '処理中…',
modelUnavailable: modelUnavailable:
'Space モデルを利用できません。設定でログインとモデルの権限を確認して、新しい会話を開始してください。', 'モデルを利用できません。設定と権限を確認して、新しい会話を開始してください。',
error: error:
'処理が完了しませんでした。新しい会話の前にリソースを確認してください。変更は自動で再試行されません。', '処理が完了しませんでした。新しい会話の前にリソースを確認してください。変更は自動で再試行されません。',
running: running:
+4 -4
View File
@@ -1,6 +1,6 @@
const zhHans = { const zhHans = {
assistant: { assistant: {
modelHint: '助手模型 · 默认使用 Space 推荐模型,切换从下一条消息生效', modelHint: '切换助手模型,从下一条消息生效',
details: '查看原始数据', details: '查看原始数据',
found: '找到 {{count}} 项', found: '找到 {{count}} 项',
completed: '已完成', completed: '已完成',
@@ -26,8 +26,8 @@ const zhHans = {
knowledge_bases: '查询知识库', knowledge_bases: '查询知识库',
knowledge_engines: '查询知识引擎', knowledge_engines: '查询知识引擎',
}, },
title: '工作区助手 · 实验版', title: '工作区助手',
subtitle: '使用 Space 模型构建应用', subtitle: '构建和管理你的应用',
newChat: '新对话', newChat: '新对话',
close: '关闭', close: '关闭',
welcome: welcome:
@@ -40,7 +40,7 @@ const zhHans = {
decline: '拒绝', decline: '拒绝',
working: '正在处理…', working: '正在处理…',
modelUnavailable: modelUnavailable:
'Space 模型暂不可用。请在设置中检查 Space 登录和模型权限,然后开启新对话。', '模型暂不可用。请检查模型配置和访问权限,然后开启新对话。',
error: error:
'本轮未完成。请先检查资源和操作结果,再开启新对话;系统不会自动重试变更。', '本轮未完成。请先检查资源和操作结果,再开启新对话;系统不会自动重试变更。',
running: running: