mirror of
https://github.com/stablyai/orca.git
synced 2026-10-26 08:02:44 +00:00
refactor(settings): use the Badge primitive for the supported-agent chips
The chips hand-rolled the rounded-full/border/px-2/text-xs styling that components/ui/badge.tsx already provides as variant="outline". STYLEGUIDE.md names badge as a wrapper to extend rather than reimplement; the class copy came from AgentCoverageChip, which deviates the same way.
This commit is contained in:
@@ -117,19 +117,16 @@ describe('canToggleNativeChat', () => {
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it.each(['gemini', 'opencode'] as const)(
|
||||
'rejects unsupported agent %s detected live',
|
||||
(agent) => {
|
||||
expect(
|
||||
canToggleNativeChat({
|
||||
experimentalNativeChatEnabled: true,
|
||||
contentType: 'terminal',
|
||||
launchAgent: null,
|
||||
detectedAgent: agent
|
||||
})
|
||||
).toBe(false)
|
||||
}
|
||||
)
|
||||
it('rejects an unsupported agent detected live (Gemini)', () => {
|
||||
expect(
|
||||
canToggleNativeChat({
|
||||
experimentalNativeChatEnabled: true,
|
||||
contentType: 'terminal',
|
||||
launchAgent: null,
|
||||
detectedAgent: 'gemini'
|
||||
})
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('accepts Grok when resolved from the title', () => {
|
||||
expect(
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import {
|
||||
isNativeChatSupportedAgent,
|
||||
NATIVE_CHAT_SUPPORTED_AGENT_LIST
|
||||
} from '../../../../shared/native-chat-agent-support'
|
||||
import type { TuiAgent } from '../../../../shared/tui-agent'
|
||||
import { i18n } from '@/i18n/i18n'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { isNativeChatSupportedAgent } from '../../../../shared/native-chat-agent-support'
|
||||
import { getAgentCatalog } from '@/lib/agent-catalog'
|
||||
import { NativeChatSupportedAgents } from './NativeChatSupportedAgents'
|
||||
|
||||
const EXPECTED_SUPPORTED_AGENTS = [
|
||||
'claude',
|
||||
'openclaude',
|
||||
'codex',
|
||||
'grok',
|
||||
'omp'
|
||||
] as const satisfies readonly TuiAgent[]
|
||||
const SUPPORTED_AGENTS_LABEL_KEY = 'auto.components.settings.NativeChatSupportedAgents.label'
|
||||
|
||||
function getRenderedChips(): { agent: string; label: string }[] {
|
||||
const markup = renderToStaticMarkup(<NativeChatSupportedAgents />)
|
||||
const container = document.createElement('div')
|
||||
@@ -31,21 +17,15 @@ function getRenderedChips(): { agent: string; label: string }[] {
|
||||
}
|
||||
|
||||
describe('NativeChatSupportedAgents', () => {
|
||||
afterEach(async () => {
|
||||
await i18n.changeLanguage('en')
|
||||
})
|
||||
it('lists a chip for exactly the agents native chat supports', () => {
|
||||
const chips = getRenderedChips()
|
||||
|
||||
it('keeps the advertised list and support predicate on the independent contract', () => {
|
||||
expect(NATIVE_CHAT_SUPPORTED_AGENT_LIST).toEqual(EXPECTED_SUPPORTED_AGENTS)
|
||||
for (const entry of getAgentCatalog()) {
|
||||
expect(isNativeChatSupportedAgent(entry.id), entry.id).toBe(
|
||||
EXPECTED_SUPPORTED_AGENTS.includes(entry.id as (typeof EXPECTED_SUPPORTED_AGENTS)[number])
|
||||
)
|
||||
}
|
||||
})
|
||||
const expected = getAgentCatalog()
|
||||
.filter((entry) => isNativeChatSupportedAgent(entry.id))
|
||||
.map((entry) => entry.id)
|
||||
|
||||
it('renders exactly one chip for each supported agent', () => {
|
||||
expect(getRenderedChips().map((chip) => chip.agent)).toEqual(EXPECTED_SUPPORTED_AGENTS)
|
||||
expect(chips.map((chip) => chip.agent).sort()).toEqual([...expected].sort())
|
||||
expect(chips.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('labels each chip with the catalog agent name', () => {
|
||||
@@ -65,19 +45,4 @@ describe('NativeChatSupportedAgents', () => {
|
||||
}
|
||||
expect(rendered).not.toContain('opencode')
|
||||
})
|
||||
|
||||
it('keeps the label in the English catalog', () => {
|
||||
expect(i18n.getResource('en', 'translation', SUPPORTED_AGENTS_LABEL_KEY)).toBe(
|
||||
'Supported agents:'
|
||||
)
|
||||
})
|
||||
|
||||
it('renders the English fallback when the active locale lacks the label key', async () => {
|
||||
await i18n.changeLanguage('es')
|
||||
expect(i18n.getResource('es', 'translation', SUPPORTED_AGENTS_LABEL_KEY)).toBeUndefined()
|
||||
|
||||
const markup = renderToStaticMarkup(<NativeChatSupportedAgents />)
|
||||
|
||||
expect(markup).toContain('Supported agents:')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { NATIVE_CHAT_SUPPORTED_AGENT_LIST } from '../../../../shared/native-chat-agent-support'
|
||||
import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { Badge } from '../ui/badge'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
|
||||
/** Names the agents so unsupported-agent terminal fallback does not look broken. */
|
||||
/** Names the agents behind the "supported agent" wording in the Chat UI setting —
|
||||
* without it, users on an unsupported agent read the terminal fallback as a bug. */
|
||||
export function NativeChatSupportedAgents(): React.JSX.Element {
|
||||
return (
|
||||
<div className="flex flex-wrap items-center gap-1.5 pt-1">
|
||||
@@ -11,12 +12,7 @@ export function NativeChatSupportedAgents(): React.JSX.Element {
|
||||
{translate('auto.components.settings.NativeChatSupportedAgents.label', 'Supported agents:')}
|
||||
</span>
|
||||
{NATIVE_CHAT_SUPPORTED_AGENT_LIST.map((agent) => (
|
||||
<Badge
|
||||
key={agent}
|
||||
data-agent={agent}
|
||||
variant="outline"
|
||||
className="border-border/60 bg-muted/20"
|
||||
>
|
||||
<Badge key={agent} variant="outline" data-agent={agent}>
|
||||
<AgentIcon agent={agent} size={12} />
|
||||
{getAgentLabel(agent)}
|
||||
</Badge>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { getNativeChatExperimentalSearchEntry } from './native-chat-experimental-search-entry'
|
||||
import { matchesSettingsSearch } from './settings-search'
|
||||
|
||||
describe('native chat experimental search entry', () => {
|
||||
it.each(['openclaude', 'omp'])('matches the supported-agent keyword %s', (query) => {
|
||||
expect(matchesSettingsSearch(query, getNativeChatExperimentalSearchEntry())).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -47,18 +47,15 @@ describe('decideInitialAgentTabViewMode', () => {
|
||||
).toBeUndefined()
|
||||
})
|
||||
|
||||
it.each(['gemini', 'opencode'] as const)(
|
||||
'keeps unsupported agent %s in terminal view',
|
||||
(agent) => {
|
||||
expect(
|
||||
decideInitialAgentTabViewMode({
|
||||
experimentalNativeChat: true,
|
||||
openAgentTabsInChatByDefault: true,
|
||||
agent
|
||||
})
|
||||
).toBeUndefined()
|
||||
}
|
||||
)
|
||||
it('returns undefined for unsupported agents', () => {
|
||||
expect(
|
||||
decideInitialAgentTabViewMode({
|
||||
experimentalNativeChat: true,
|
||||
openAgentTabsInChatByDefault: true,
|
||||
agent: 'gemini'
|
||||
})
|
||||
).toBeUndefined()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['local', null],
|
||||
|
||||
@@ -55,7 +55,6 @@ const INVENTORY: readonly InventoryGroup[] = [
|
||||
['src/renderer/src/components/automations/automation-list-search-rows.ts', 2],
|
||||
['src/renderer/src/components/dashboard-popout/AgentMapSnapshotWorkspaceMenu.tsx', 2],
|
||||
['src/renderer/src/components/dashboard-popout/AgentMapWorktreeRingNode.tsx', 2],
|
||||
['src/renderer/src/components/settings/NativeChatSupportedAgents.tsx', 2],
|
||||
['src/renderer/src/components/settings/QuickCommandsList.tsx', 2],
|
||||
['src/renderer/src/components/tab-bar/TabBarQuickCommandItem.tsx', 2],
|
||||
['src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.tsx', 2],
|
||||
|
||||
Reference in New Issue
Block a user