Let the reader choose Owliver's language, and stop the suggestion row going silent
Some checks failed
CI / check (pull_request) Failing after 5m8s
Some checks failed
CI / check (pull_request) Failing after 5m8s
Two changes to the assistant panel. THE LANGUAGE SELECTOR. An account setting in the header menu, not a property of the conversation: somebody who reads in Spanish reads in Spanish on every page and after every reload, and making it per-thread would ask them to set it again each time the panel opened. Held in localStorage and outside React, so the Owliver panel — a different subtree from the header — sees the change without a provider spanning both, and a second tab picks it up. A TAG is sent, never a sentence, and the field is omitted entirely when the choice is English. The backend maps it onto a closed set (internal/runtime/language.go holds the same list) and an unrecognised tag answers in English. The panel therefore cannot write prompt text from here, which is the point: the selected string SELECTS a directive rather than becoming one. THE SUGGESTION ROW. It appeared exactly once per conversation and was silent after that, whatever was asked. Every chip ever SHOWN was banned permanently in a set that only grew; the server keeps returning the top of the same small catalogue, so by the second turn every suggestion was already in it, the filter emptied the list, and an empty list draws no row. Asked and offered are not the same thing. A question this thread actually PUT is excluded for good — it has an answer on screen and offering to repeat it is not a follow-up. A chip merely DISPLAYED and passed over is held back only from the turn directly after it, which is enough to stop the row redrawing verbatim under consecutive answers; beyond that it is offerable again, because ignoring a suggestion is not the same as having covered it. Verified: 1710/1710 skill-checks, a clean typecheck, build and lint. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
Bell, ChevronDown, LayoutGrid, LogOut, Menu, Search, Settings, Shield,
|
||||
Bell, ChevronDown, Globe, LayoutGrid, LogOut, Menu, Search, Settings, Shield,
|
||||
} from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { base44 } from '@/api/base44Client';
|
||||
@@ -11,10 +11,13 @@ import { Avatar } from '@/components/ds/Avatar';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import {
|
||||
DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel,
|
||||
DropdownMenuSeparator, DropdownMenuTrigger,
|
||||
DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger, DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
|
||||
import { AssistantPanel, AssistantPanelProvider } from '@/components/ai-assistant';
|
||||
import { LANGUAGES, setLanguage, useLanguage } from '@/components/ai-assistant/language';
|
||||
import { UiEditingProvider } from '@/components/ui-tree/UiEditingProvider';
|
||||
import { pageKeyForRoute } from '@/lib/skills/registry';
|
||||
import { endAdminSession } from '@/lib/admin/session';
|
||||
@@ -164,6 +167,11 @@ export default function AdminLayout() {
|
||||
const navigate = useNavigate();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
/* The account's language. Held outside React so the Owliver panel — a
|
||||
different subtree entirely — sees the change without a provider spanning
|
||||
both, and so a second tab picks it up. See ai-assistant/language. */
|
||||
const language = useLanguage();
|
||||
|
||||
/* Shared cache rather than a local fetch, so saving the profile updates the
|
||||
header avatar and account menu without a reload. */
|
||||
const { data: user } = useCurrentUser();
|
||||
@@ -289,6 +297,45 @@ export default function AdminLayout() {
|
||||
<DropdownMenuItem onClick={() => navigate('/admin/workspace/agents')} className="cursor-pointer">
|
||||
<LayoutGrid className="mr-2 h-4 w-4" /> Agent Registry
|
||||
</DropdownMenuItem>
|
||||
|
||||
{/* Language.
|
||||
|
||||
A submenu rather than a row that navigates, because there
|
||||
is nothing to navigate TO: the whole setting is one choice
|
||||
from a closed list, and a page built to hold a single
|
||||
radio group would be a page nobody returns to.
|
||||
|
||||
A radio group rather than two items, so the control states
|
||||
what it is — one of these, exactly one selected — to a
|
||||
screen reader and to the eye, without the menu having to
|
||||
draw its own tick.
|
||||
|
||||
What it governs is Owliver's replies. Nothing else in the
|
||||
product is generated text, so nothing else changes; the
|
||||
row is in the account menu rather than in the panel
|
||||
because it is a property of the account and outlives any
|
||||
one conversation. */}
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger className="cursor-pointer">
|
||||
<Globe className="mr-2 h-4 w-4" /> Language
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
<DropdownMenuRadioGroup value={language} onValueChange={setLanguage}>
|
||||
{LANGUAGES.map((lang) => (
|
||||
<DropdownMenuRadioItem
|
||||
key={lang.tag}
|
||||
value={lang.tag}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{lang.label}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
onClick={signOut}
|
||||
|
||||
Reference in New Issue
Block a user