feat: make agent switching shortcut configurable (#1186)

Adds Cycle Agent to shortcut settings with Tab as the default
Applies custom shortcut in chat input and model selector
Updates help dialog to show saved shortcut values
This commit is contained in:
Bohdan Triapitsyn
2026-05-15 00:27:39 +03:00
parent 8c226afbbb
commit ba019c05a6
19 changed files with 139 additions and 17 deletions
+19 -4
View File
@@ -62,6 +62,7 @@ import { useI18n } from '@/lib/i18n';
import { fetchResponseStyleInstruction } from '@/lib/responseStyle'; import { fetchResponseStyleInstruction } from '@/lib/responseStyle';
import { wrapSystemReminder } from '@/lib/systemReminder'; import { wrapSystemReminder } from '@/lib/systemReminder';
import { getSyncMessages } from '@/sync/sync-refs'; import { getSyncMessages } from '@/sync/sync-refs';
import { eventMatchesShortcut, getEffectiveShortcutCombo, normalizeCombo } from '@/lib/shortcuts';
const MAX_VISIBLE_TEXTAREA_LINES = 8; const MAX_VISIBLE_TEXTAREA_LINES = 8;
const EMPTY_QUEUE: QueuedMessage[] = []; const EMPTY_QUEUE: QueuedMessage[] = [];
@@ -791,6 +792,10 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
const isExpandedInput = useUIStore((state) => state.isExpandedInput); const isExpandedInput = useUIStore((state) => state.isExpandedInput);
const setExpandedInput = useUIStore((state) => state.setExpandedInput); const setExpandedInput = useUIStore((state) => state.setExpandedInput);
const setTimelineDialogOpen = useUIStore((state) => state.setTimelineDialogOpen); const setTimelineDialogOpen = useUIStore((state) => state.setTimelineDialogOpen);
const cycleAgentShortcutOverride = useUIStore((state) => state.shortcutOverrides.cycle_agent);
const cycleAgentShortcut = React.useMemo(() => (
getEffectiveShortcutCombo('cycle_agent', cycleAgentShortcutOverride ? { cycle_agent: cycleAgentShortcutOverride } : undefined)
), [cycleAgentShortcutOverride]);
const { git: runtimeGit } = useRuntimeAPIs(); const { git: runtimeGit } = useRuntimeAPIs();
const { currentTheme } = useThemeSystem(); const { currentTheme } = useThemeSystem();
const chatSearchDirectory = useChatSearchDirectory(); const chatSearchDirectory = useChatSearchDirectory();
@@ -1762,9 +1767,19 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
return; return;
} }
if (e.key === 'Tab' && !showCommandAutocomplete && !showSkillAutocomplete && !showFileMention) { const cycleAgentBackwardShortcut = cycleAgentShortcut && !cycleAgentShortcut.includes('shift')
? normalizeCombo(`shift+${cycleAgentShortcut}`)
: '';
const cycleAgentDirection = cycleAgentBackwardShortcut && eventMatchesShortcut(e, cycleAgentBackwardShortcut)
? -1
: eventMatchesShortcut(e, cycleAgentShortcut)
? 1
: 0;
if (cycleAgentDirection !== 0 && !showCommandAutocomplete && !showSkillAutocomplete && !showFileMention) {
e.preventDefault(); e.preventDefault();
handleCycleAgent(); e.stopPropagation();
handleCycleAgent(cycleAgentDirection);
return; return;
} }
@@ -1988,8 +2003,8 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
void abortCurrentOperation(currentSessionId || undefined); void abortCurrentOperation(currentSessionId || undefined);
}, [abortCurrentOperation, clearAbortPrompt, currentSessionId, startAbortIndicator]); }, [abortCurrentOperation, clearAbortPrompt, currentSessionId, startAbortIndicator]);
const handleCycleAgent = React.useCallback(() => { const handleCycleAgent = React.useCallback((direction: 1 | -1 = 1) => {
const nextAgentName = getCycledPrimaryAgentName(agents, currentAgentName); const nextAgentName = getCycledPrimaryAgentName(agents, currentAgentName, direction);
if (!nextAgentName) return; if (!nextAgentName) return;
setAgent(nextAgentName); setAgent(nextAgentName);
@@ -46,6 +46,7 @@ import { useIsTextTruncated } from '@/hooks/useIsTextTruncated';
import { formatEffortLabel, getCycledPrimaryAgentName, type MobileControlsPanel } from './mobileControlsUtils'; import { formatEffortLabel, getCycledPrimaryAgentName, type MobileControlsPanel } from './mobileControlsUtils';
import { useI18n } from '@/lib/i18n'; import { useI18n } from '@/lib/i18n';
import { useOpenCodeReadiness } from '@/hooks/useOpenCodeReadiness'; import { useOpenCodeReadiness } from '@/hooks/useOpenCodeReadiness';
import { eventMatchesShortcut, formatShortcutForDisplay, getEffectiveShortcutCombo, normalizeCombo } from '@/lib/shortcuts';
type IconComponent = IconName; type IconComponent = IconName;
@@ -429,6 +430,11 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen); const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
const setSettingsPage = useUIStore((state) => state.setSettingsPage); const setSettingsPage = useUIStore((state) => state.setSettingsPage);
const hiddenModels = useUIStore((state) => state.hiddenModels); const hiddenModels = useUIStore((state) => state.hiddenModels);
const cycleAgentShortcutOverride = useUIStore((state) => state.shortcutOverrides.cycle_agent);
const cycleAgentShortcut = React.useMemo(() => (
getEffectiveShortcutCombo('cycle_agent', cycleAgentShortcutOverride ? { cycle_agent: cycleAgentShortcutOverride } : undefined)
), [cycleAgentShortcutOverride]);
const cycleAgentShortcutLabel = React.useMemo(() => formatShortcutForDisplay(cycleAgentShortcut), [cycleAgentShortcut]);
const collapsedProviderSet = React.useMemo(() => { const collapsedProviderSet = React.useMemo(() => {
const result = new Set<string>(); const result = new Set<string>();
for (const providerId of collapsedModelProviders) { for (const providerId of collapsedModelProviders) {
@@ -1299,6 +1305,22 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
handleAgentChange(nextAgentName, { closeModelSelector: false }); handleAgentChange(nextAgentName, { closeModelSelector: false });
}, [agents, currentAgentName, handleAgentChange]); }, [agents, currentAgentName, handleAgentChange]);
const getCycleAgentDirectionFromEvent = React.useCallback((event: KeyboardEvent | React.KeyboardEvent): 1 | -1 | null => {
const cycleAgentBackwardShortcut = cycleAgentShortcut && !cycleAgentShortcut.includes('shift')
? normalizeCombo(`shift+${cycleAgentShortcut}`)
: '';
if (cycleAgentBackwardShortcut && eventMatchesShortcut(event, cycleAgentBackwardShortcut)) {
return -1;
}
if (eventMatchesShortcut(event, cycleAgentShortcut)) {
return 1;
}
return null;
}, [cycleAgentShortcut]);
const handleProviderAndModelChange = ( const handleProviderAndModelChange = (
providerId: string, providerId: string,
modelId: string, modelId: string,
@@ -2566,9 +2588,10 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
e.stopPropagation(); e.stopPropagation();
keyboardOwnsModelSelectionRef.current = true; keyboardOwnsModelSelectionRef.current = true;
if (e.key === 'Tab') { const cycleAgentDirection = getCycleAgentDirectionFromEvent(e);
if (cycleAgentDirection) {
e.preventDefault(); e.preventDefault();
handleCycleAgentFromModelPicker(e.shiftKey ? -1 : 1); handleCycleAgentFromModelPicker(cycleAgentDirection);
} else if (e.key === 'ArrowDown') { } else if (e.key === 'ArrowDown') {
e.preventDefault(); e.preventDefault();
setModelSelectedIndex((prev) => (prev + 1) % Math.max(1, totalItems)); setModelSelectedIndex((prev) => (prev + 1) % Math.max(1, totalItems));
@@ -2641,6 +2664,18 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
} }
}; };
const handleModelShortcutKeyDownCapture = (e: React.KeyboardEvent) => {
const cycleAgentDirection = getCycleAgentDirectionFromEvent(e);
if (!cycleAgentDirection) {
return;
}
e.preventDefault();
e.stopPropagation();
keyboardOwnsModelSelectionRef.current = true;
handleCycleAgentFromModelPicker(cycleAgentDirection);
};
const handleFavoriteDragEnd = (event: DragEndEvent) => { const handleFavoriteDragEnd = (event: DragEndEvent) => {
const { active, over } = event; const { active, over } = event;
if (!over || active.id === over.id) { if (!over || active.id === over.id) {
@@ -2729,7 +2764,12 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
</div> </div>
</DropdownMenuTrigger> </DropdownMenuTrigger>
</TooltipTrigger> </TooltipTrigger>
<DropdownMenuContent className="w-[min(380px,calc(100vw-2rem))] p-0 flex flex-col" align="end" alignOffset={-40}> <DropdownMenuContent
className="w-[min(380px,calc(100vw-2rem))] p-0 flex flex-col"
align="end"
alignOffset={-40}
onKeyDownCapture={handleModelShortcutKeyDownCapture}
>
{/* Search Input */} {/* Search Input */}
<div className="p-2 border-b border-border/40"> <div className="p-2 border-b border-border/40">
<div className="relative"> <div className="relative">
@@ -2919,7 +2959,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
<div className="px-3 pt-1 pb-1.5 border-t border-border/40 typography-micro text-muted-foreground"> <div className="px-3 pt-1 pb-1.5 border-t border-border/40 typography-micro text-muted-foreground">
<div className="flex items-center gap-x-2 whitespace-nowrap overflow-hidden"> <div className="flex items-center gap-x-2 whitespace-nowrap overflow-hidden">
<span>{t('chat.modelControls.keyboardHintNavigate')}</span> <span>{t('chat.modelControls.keyboardHintNavigate')}</span>
<span>{t('chat.modelControls.keyboardHintSwitchAgent')}</span> <span>{t('chat.modelControls.keyboardHintSwitchAgent', { shortcut: cycleAgentShortcutLabel })}</span>
<span className={cn(!highlightedSupportsThinking && 'invisible')}> <span className={cn(!highlightedSupportsThinking && 'invisible')}>
{t('chat.modelControls.keyboardHintThinking')} {t('chat.modelControls.keyboardHintThinking')}
</span> </span>
+2 -1
View File
@@ -64,7 +64,8 @@ export const HelpDialog: React.FC = () => {
keys: '', keys: '',
}, },
{ {
keys: ["Tab"], id: 'cycle_agent',
keys: '',
descriptionKey: "helpDialog.item.cycleAgent", descriptionKey: "helpDialog.item.cycleAgent",
icon: "ai-agent", icon: "ai-agent",
}, },
+53 -1
View File
@@ -9,9 +9,10 @@ import { createWorktreeSession } from '@/lib/worktreeSessionCreator';
import { useConfigStore } from '@/stores/useConfigStore'; import { useConfigStore } from '@/stores/useConfigStore';
import { canUseElectronDesktopIPC, invokeDesktop, isVSCodeRuntime } from '@/lib/desktop'; import { canUseElectronDesktopIPC, invokeDesktop, isVSCodeRuntime } from '@/lib/desktop';
import { showOpenCodeStatus } from '@/lib/openCodeStatus'; import { showOpenCodeStatus } from '@/lib/openCodeStatus';
import { eventMatchesShortcut, getEffectiveShortcutCombo } from '@/lib/shortcuts'; import { eventMatchesShortcut, getEffectiveShortcutCombo, normalizeCombo } from '@/lib/shortcuts';
import { useDirectoryStore } from '@/stores/useDirectoryStore'; import { useDirectoryStore } from '@/stores/useDirectoryStore';
import { useProjectsStore } from '@/stores/useProjectsStore'; import { useProjectsStore } from '@/stores/useProjectsStore';
import { getCycledPrimaryAgentName } from '@/components/chat/mobileControlsUtils';
export const useKeyboardShortcuts = () => { export const useKeyboardShortcuts = () => {
const openNewSessionDraft = useSessionUIStore((s) => s.openNewSessionDraft); const openNewSessionDraft = useSessionUIStore((s) => s.openNewSessionDraft);
@@ -101,6 +102,10 @@ export const useKeyboardShortcuts = () => {
return; return;
} }
const isChatInputTarget = (target: EventTarget | null) => {
return target instanceof HTMLTextAreaElement && target.getAttribute('data-chat-input') === 'true';
};
if (eventMatchesShortcut(e, combo('open_command_palette'))) { if (eventMatchesShortcut(e, combo('open_command_palette'))) {
e.preventDefault(); e.preventDefault();
toggleCommandPalette(); toggleCommandPalette();
@@ -200,6 +205,53 @@ export const useKeyboardShortcuts = () => {
return; return;
} }
const cycleAgentCombo = combo('cycle_agent');
const cycleAgentBackwardCombo = cycleAgentCombo && !cycleAgentCombo.includes('shift')
? normalizeCombo(`shift+${cycleAgentCombo}`)
: '';
const cycleAgentDirection = cycleAgentBackwardCombo && eventMatchesShortcut(e, cycleAgentBackwardCombo)
? -1
: eventMatchesShortcut(e, cycleAgentCombo)
? 1
: 0;
if (cycleAgentDirection !== 0) {
const {
isSettingsDialogOpen,
isCommandPaletteOpen,
isHelpDialogOpen,
isSessionSwitcherOpen,
isAboutDialogOpen,
activeMainTab,
} = useUIStore.getState();
const hasOverlay = isSettingsDialogOpen || isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
if (hasOverlay || activeMainTab !== 'chat' || !isChatInputTarget(e.target)) {
return;
}
const configState = useConfigStore.getState();
const nextAgentName = getCycledPrimaryAgentName(
configState.getVisibleAgents(),
configState.currentAgentName,
cycleAgentDirection,
);
if (!nextAgentName) {
return;
}
e.preventDefault();
configState.setAgent(nextAgentName);
useUIStore.getState().addRecentAgent(nextAgentName);
const sessionId = useSessionUIStore.getState().currentSessionId;
if (sessionId) {
useSelectionStore.getState().saveSessionAgentSelection(sessionId, nextAgentName);
}
return;
}
if (eventMatchesShortcut(e, combo('toggle_right_sidebar'))) { if (eventMatchesShortcut(e, combo('toggle_right_sidebar'))) {
const { isMobile } = useUIStore.getState(); const { isMobile } = useUIStore.getState();
if (isMobile) { if (isMobile) {
@@ -759,6 +759,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': 'Toggle services menu', 'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': 'Toggle services menu',
'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': 'Cycle services tab', 'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': 'Cycle services tab',
'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': 'Cycle theme', 'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': 'Cycle theme',
'settings.openchamber.keyboardShortcuts.action.cycle_agent.label': 'Cycle agent',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': 'Cycle favorite model forward', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': 'Cycle favorite model forward',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': 'Cycle favorite model backward', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': 'Cycle favorite model backward',
'settings.openchamber.keyboardShortcuts.action.expand_input.label': 'Expand input', 'settings.openchamber.keyboardShortcuts.action.expand_input.label': 'Expand input',
+1 -1
View File
@@ -1641,7 +1641,7 @@ export const dict = {
'chat.modelControls.expandProvider': 'Expand provider', 'chat.modelControls.expandProvider': 'Expand provider',
'chat.modelControls.keyboardHint': '↑↓ navigate{thinking} • Enter select • Esc close', 'chat.modelControls.keyboardHint': '↑↓ navigate{thinking} • Enter select • Esc close',
'chat.modelControls.keyboardHintNavigate': '↑↓ navigate', 'chat.modelControls.keyboardHintNavigate': '↑↓ navigate',
'chat.modelControls.keyboardHintSwitchAgent': 'Tab switch agent', 'chat.modelControls.keyboardHintSwitchAgent': '{shortcut} switch agent',
'chat.modelControls.keyboardHintThinking': '←→ thinking', 'chat.modelControls.keyboardHintThinking': '←→ thinking',
'chat.modelControls.showThinkingModes': 'Show thinking modes', 'chat.modelControls.showThinkingModes': 'Show thinking modes',
'chat.modelControls.hideThinkingModes': 'Hide thinking modes', 'chat.modelControls.hideThinkingModes': 'Hide thinking modes',
@@ -759,6 +759,7 @@ export const settingsDict = {
"settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Mostrar u ocultar menú de servicios", "settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Mostrar u ocultar menú de servicios",
"settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Cambiar pestaña de servicios", "settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Cambiar pestaña de servicios",
"settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Cambiar tema", "settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Cambiar tema",
"settings.openchamber.keyboardShortcuts.action.cycle_agent.label": "Cambiar agente",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Siguiente modelo favorito", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Siguiente modelo favorito",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Modelo favorito anterior", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Modelo favorito anterior",
"settings.openchamber.keyboardShortcuts.action.expand_input.label": "Expandir entrada", "settings.openchamber.keyboardShortcuts.action.expand_input.label": "Expandir entrada",
+1 -1
View File
@@ -1607,7 +1607,7 @@ export const dict: Record<I18nKey, string> = {
"chat.modelControls.expandProvider": "Expandir proveedor", "chat.modelControls.expandProvider": "Expandir proveedor",
"chat.modelControls.keyboardHint": "↑↓ navegar{thinking} • Enter seleccionar • Esc cerrar", "chat.modelControls.keyboardHint": "↑↓ navegar{thinking} • Enter seleccionar • Esc cerrar",
"chat.modelControls.keyboardHintNavigate": "↑↓ navegar", "chat.modelControls.keyboardHintNavigate": "↑↓ navegar",
"chat.modelControls.keyboardHintSwitchAgent": "Tab cambiar agente", "chat.modelControls.keyboardHintSwitchAgent": "{shortcut} cambiar agente",
"chat.modelControls.keyboardHintThinking": "←→ cambiar razonamiento", "chat.modelControls.keyboardHintThinking": "←→ cambiar razonamiento",
"chat.modelControls.showThinkingModes": "Mostrar modos de razonamiento", "chat.modelControls.showThinkingModes": "Mostrar modos de razonamiento",
"chat.modelControls.hideThinkingModes": "Ocultar modos de razonamiento", "chat.modelControls.hideThinkingModes": "Ocultar modos de razonamiento",
@@ -759,6 +759,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': '서비스 메뉴 토글', 'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': '서비스 메뉴 토글',
'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': '서비스 탭 순환', 'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': '서비스 탭 순환',
'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': '테마 순환', 'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': '테마 순환',
'settings.openchamber.keyboardShortcuts.action.cycle_agent.label': '에이전트 순환',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': '즐겨찾기 모델 앞으로 순환', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': '즐겨찾기 모델 앞으로 순환',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': '즐겨찾기 모델 뒤로 순환', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': '즐겨찾기 모델 뒤로 순환',
'settings.openchamber.keyboardShortcuts.action.expand_input.label': '입력 확장', 'settings.openchamber.keyboardShortcuts.action.expand_input.label': '입력 확장',
+1 -1
View File
@@ -1641,7 +1641,7 @@ export const dict: Record<I18nKey, string> = {
'chat.modelControls.expandProvider': '펼치기 프로바이더', 'chat.modelControls.expandProvider': '펼치기 프로바이더',
'chat.modelControls.keyboardHint': '↑↓ 이동 {thinking} • Enter 선택 • Esc 닫기', 'chat.modelControls.keyboardHint': '↑↓ 이동 {thinking} • Enter 선택 • Esc 닫기',
'chat.modelControls.keyboardHintNavigate': '↑↓ 이동', 'chat.modelControls.keyboardHintNavigate': '↑↓ 이동',
'chat.modelControls.keyboardHintSwitchAgent': 'Tab 에이전트 전환', 'chat.modelControls.keyboardHintSwitchAgent': '{shortcut} 에이전트 전환',
'chat.modelControls.keyboardHintThinking': '←→ 추론', 'chat.modelControls.keyboardHintThinking': '←→ 추론',
'chat.modelControls.showThinkingModes': '추론 모드 표시', 'chat.modelControls.showThinkingModes': '추론 모드 표시',
'chat.modelControls.hideThinkingModes': '추론 모드 숨기기', 'chat.modelControls.hideThinkingModes': '추론 모드 숨기기',
@@ -598,6 +598,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.cycle_right_sidebar_tab.label': 'Przełącz zakładkę prawego paska bocznego', 'settings.openchamber.keyboardShortcuts.action.cycle_right_sidebar_tab.label': 'Przełącz zakładkę prawego paska bocznego',
'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': 'Przełącz zakładkę usług', 'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': 'Przełącz zakładkę usług',
'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': 'Przełącz motyw', 'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': 'Przełącz motyw',
'settings.openchamber.keyboardShortcuts.action.cycle_agent.label': 'Przełącz agenta',
'settings.openchamber.keyboardShortcuts.action.expand_input.label': 'Rozwiń pole wprowadzania', 'settings.openchamber.keyboardShortcuts.action.expand_input.label': 'Rozwiń pole wprowadzania',
'settings.openchamber.keyboardShortcuts.action.focus_input.label': 'Skup pole wprowadzania', 'settings.openchamber.keyboardShortcuts.action.focus_input.label': 'Skup pole wprowadzania',
'settings.openchamber.keyboardShortcuts.action.new_chat.label': 'Nowa sesja', 'settings.openchamber.keyboardShortcuts.action.new_chat.label': 'Nowa sesja',
+1 -1
View File
@@ -896,7 +896,7 @@ export const dict: Record<I18nKey, string> = {
'chat.modelControls.input': 'Wejście', 'chat.modelControls.input': 'Wejście',
'chat.modelControls.keyboardHint': '↑↓ nawigacja{thinking} • Enter wybór • Esc zamknij', 'chat.modelControls.keyboardHint': '↑↓ nawigacja{thinking} • Enter wybór • Esc zamknij',
'chat.modelControls.keyboardHintNavigate': '↑↓ nawigacja', 'chat.modelControls.keyboardHintNavigate': '↑↓ nawigacja',
'chat.modelControls.keyboardHintSwitchAgent': 'Tab przełącz agenta', 'chat.modelControls.keyboardHintSwitchAgent': '{shortcut} przełącz agenta',
'chat.modelControls.keyboardHintThinking': '←→ myślenie', 'chat.modelControls.keyboardHintThinking': '←→ myślenie',
'chat.modelControls.knowledge': 'Wiedza', 'chat.modelControls.knowledge': 'Wiedza',
'chat.modelControls.limits': 'Limity', 'chat.modelControls.limits': 'Limity',
@@ -759,6 +759,7 @@ export const settingsDict = {
"settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Mostrar ou ocultar menu de serviços", "settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Mostrar ou ocultar menu de serviços",
"settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Alternar aba de serviços", "settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Alternar aba de serviços",
"settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Alternar tema", "settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Alternar tema",
"settings.openchamber.keyboardShortcuts.action.cycle_agent.label": "Alternar agente",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Próximo modelo favorito", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Próximo modelo favorito",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Modelo favorito anterior", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Modelo favorito anterior",
"settings.openchamber.keyboardShortcuts.action.expand_input.label": "Expandir entrada", "settings.openchamber.keyboardShortcuts.action.expand_input.label": "Expandir entrada",
+1 -1
View File
@@ -1607,7 +1607,7 @@ export const dict: Record<I18nKey, string> = {
"chat.modelControls.expandProvider": "Expandir provedor", "chat.modelControls.expandProvider": "Expandir provedor",
"chat.modelControls.keyboardHint": "↑↓ navegar{thinking} • Enter selecionar • Esc fechar", "chat.modelControls.keyboardHint": "↑↓ navegar{thinking} • Enter selecionar • Esc fechar",
"chat.modelControls.keyboardHintNavigate": "↑↓ navegar", "chat.modelControls.keyboardHintNavigate": "↑↓ navegar",
"chat.modelControls.keyboardHintSwitchAgent": "Tab alternar agente", "chat.modelControls.keyboardHintSwitchAgent": "{shortcut} alternar agente",
"chat.modelControls.keyboardHintThinking": "←→ mudar raciocínio", "chat.modelControls.keyboardHintThinking": "←→ mudar raciocínio",
"chat.modelControls.showThinkingModes": "Mostrar modos de raciocínio", "chat.modelControls.showThinkingModes": "Mostrar modos de raciocínio",
"chat.modelControls.hideThinkingModes": "Ocultar modos de raciocínio", "chat.modelControls.hideThinkingModes": "Ocultar modos de raciocínio",
@@ -759,6 +759,7 @@ export const settingsDict = {
"settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Перемкнути меню сервісів", "settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label": "Перемкнути меню сервісів",
"settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Перемкнути вкладку сервісів", "settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label": "Перемкнути вкладку сервісів",
"settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Перемкнути тему", "settings.openchamber.keyboardShortcuts.action.cycle_theme.label": "Перемкнути тему",
"settings.openchamber.keyboardShortcuts.action.cycle_agent.label": "Перемкнути агента",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Перемкнути улюблену модель вперед", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label": "Перемкнути улюблену модель вперед",
"settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Перемкнути улюблену модель назад", "settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label": "Перемкнути улюблену модель назад",
"settings.openchamber.keyboardShortcuts.action.expand_input.label": "Розгорнути введення", "settings.openchamber.keyboardShortcuts.action.expand_input.label": "Розгорнути введення",
+1 -1
View File
@@ -1607,7 +1607,7 @@ export const dict: Record<I18nKey, string> = {
"chat.modelControls.expandProvider": "Розгорнути провайдера", "chat.modelControls.expandProvider": "Розгорнути провайдера",
"chat.modelControls.keyboardHint": "↑↓ навігація{thinking} • Enter вибрати • Esc закрити", "chat.modelControls.keyboardHint": "↑↓ навігація{thinking} • Enter вибрати • Esc закрити",
"chat.modelControls.keyboardHintNavigate": "↑↓ навігація", "chat.modelControls.keyboardHintNavigate": "↑↓ навігація",
"chat.modelControls.keyboardHintSwitchAgent": "Tab змінити агента", "chat.modelControls.keyboardHintSwitchAgent": "{shortcut} змінити агента",
"chat.modelControls.keyboardHintThinking": "←→ мислення", "chat.modelControls.keyboardHintThinking": "←→ мислення",
"chat.modelControls.showThinkingModes": "Показати режими мислення", "chat.modelControls.showThinkingModes": "Показати режими мислення",
"chat.modelControls.hideThinkingModes": "Приховати режими мислення", "chat.modelControls.hideThinkingModes": "Приховати режими мислення",
@@ -759,6 +759,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': '切换服务菜单', 'settings.openchamber.keyboardShortcuts.action.toggle_services_menu.label': '切换服务菜单',
'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': '轮换服务菜单标签', 'settings.openchamber.keyboardShortcuts.action.cycle_services_tab.label': '轮换服务菜单标签',
'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': '轮换主题', 'settings.openchamber.keyboardShortcuts.action.cycle_theme.label': '轮换主题',
'settings.openchamber.keyboardShortcuts.action.cycle_agent.label': '轮换智能体',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': '向前轮换收藏模型', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_forward.label': '向前轮换收藏模型',
'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': '向后轮换收藏模型', 'settings.openchamber.keyboardShortcuts.action.cycle_favorite_model_backward.label': '向后轮换收藏模型',
'settings.openchamber.keyboardShortcuts.action.expand_input.label': '展开输入框', 'settings.openchamber.keyboardShortcuts.action.expand_input.label': '展开输入框',
+1 -1
View File
@@ -1607,7 +1607,7 @@ export const dict: Record<I18nKey, string> = {
'chat.modelControls.expandProvider': '展开提供商', 'chat.modelControls.expandProvider': '展开提供商',
'chat.modelControls.keyboardHint': '↑↓ 导航{thinking} • Enter 选择 • Esc 关闭', 'chat.modelControls.keyboardHint': '↑↓ 导航{thinking} • Enter 选择 • Esc 关闭',
'chat.modelControls.keyboardHintNavigate': '↑↓ 导航', 'chat.modelControls.keyboardHintNavigate': '↑↓ 导航',
'chat.modelControls.keyboardHintSwitchAgent': 'Tab 切换智能体', 'chat.modelControls.keyboardHintSwitchAgent': '{shortcut} 切换智能体',
'chat.modelControls.keyboardHintThinking': '←→ 思考', 'chat.modelControls.keyboardHintThinking': '←→ 思考',
'chat.modelControls.showThinkingModes': '显示思考模式', 'chat.modelControls.showThinkingModes': '显示思考模式',
'chat.modelControls.hideThinkingModes': '隐藏思考模式', 'chat.modelControls.hideThinkingModes': '隐藏思考模式',
+7
View File
@@ -297,6 +297,13 @@ const SHORTCUT_ACTIONS: ReadonlyArray<ShortcutAction> = [
label: 'Cycle thinking variant', label: 'Cycle thinking variant',
description: 'Cycle thinking variant while in chat', description: 'Cycle thinking variant while in chat',
}, },
{
id: 'cycle_agent',
defaultCombo: 'tab',
label: 'Cycle agent',
description: 'Cycle agent while the model selector is open',
customizable: true,
},
{ {
id: 'cycle_favorite_model_forward', id: 'cycle_favorite_model_forward',
defaultCombo: 'ctrl+]', defaultCombo: 'ctrl+]',