Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion apps/web/src/features/agents-view/components/ModelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
type ModelRowProps,
} from '@core/component/AI/component/input/ModelCatalogPicker';
import { modelLabel } from '@core/component/AI/constant/model-label';
import { cn } from '@ui';
import type { Component, JSX } from 'solid-js';

export type ModelChoice = {
Expand All @@ -21,6 +22,9 @@ export function ModelSelector(props: {
disabled?: boolean;
modelRow?: Component<ModelRowProps>;
pending?: boolean;
/** Show only the model's logo, for phone composers. */
compact?: boolean;
triggerClass?: string;
onSelect: (id: string) => void;
onCloseAutoFocus?: (event: Event) => void;
children?: JSX.Element;
Expand All @@ -38,7 +42,12 @@ export function ModelSelector(props: {
}))}
triggerLabel={props.label}
placeholder={modelLabel(props.model)}
triggerClass="h-[33.75px] min-w-0 max-w-full gap-[5.625px] rounded-full border-0 bg-transparent hover:bg-hover px-[7.5px] text-base font-normal text-ink-muted light-mode:text-composer-placeholder [&_svg]:size-[15px]"
compact={props.compact}
triggerClass={cn(
'h-[33.75px] min-w-0 max-w-full gap-[5.625px] rounded-full border-0 bg-transparent hover:bg-hover px-[7.5px] text-base font-normal text-ink-muted light-mode:text-composer-placeholder [&_svg]:size-[15px]',
props.compact && 'size-[34px] shrink-0 justify-center p-0',
props.triggerClass
)}
ariaLabel="Model"
placement="top-end"
disabled={props.disabled}
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/features/agents-view/core/roster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ describe('rosterForAgentPicker and kindForBot', () => {
],
});

it('includes every runtime and excludes only the built-in Macro identity', () => {
it('lists built-in Macro first once and every other runtime after it', () => {
expect(rosterForAgentPicker(roster).map((a) => a.id)).toEqual([
MACRO_PERSONA_ID,
CURSOR_BOT_ID,
'bot-in-memory',
'bot-cursor',
Expand Down
16 changes: 11 additions & 5 deletions apps/web/src/features/agents-view/core/roster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,20 @@ export function buildAgentRoster(input: RosterInput): RosterAgent[] {
];
}

/** Every agent belongs in the picker; Macro is represented by model choices. */
/** Every agent belongs in the picker, Macro first; its bot aliases would repeat it. */
export function rosterForAgentPicker(
roster: readonly RosterAgent[]
): RosterAgent[] {
return roster.filter(
(agent) =>
agent.id !== MACRO_PERSONA_ID && !isMacroAgentId(agent.botId ?? agent.id)
);
return roster
.filter(
(agent) =>
agent.id === MACRO_PERSONA_ID ||
!isMacroAgentId(agent.botId ?? agent.id)
)
.sort(
(a, b) =>
Number(b.id === MACRO_PERSONA_ID) - Number(a.id === MACRO_PERSONA_ID)
);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/features/agents-view/tour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const agentsTour = defineViewTour({
entryLabel: 'Choose Chat or Code to pick an agent',
title: 'Choose your agent and model',
description:
'Open this picker to choose an agent for the current mode. In Chat, Macro’s models are listed here too; each agent’s submenu lets you choose a model for that conversation.',
'Choose the agent for the current mode here, Macro first. The model beside it uses the agent’s default; change it to use another model for your next message.',
},
{
target: AGENTS_TOUR.agentList,
Expand Down
Loading
Loading