@@ -54,6 +54,8 @@ import { PromptImageAttachments } from "./prompt-input/image-attachments"
5454import { PromptDragOverlay } from "./prompt-input/drag-overlay"
5555import { promptPlaceholder } from "./prompt-input/placeholder"
5656import { ImagePreview } from "@opencode-ai/ui/image-preview"
57+ import { useQuery } from "@tanstack/solid-query"
58+ import { loadAgentsQuery , loadProvidersQuery } from "@/context/global-sync/bootstrap"
5759
5860interface PromptInputProps {
5961 class ?: string
@@ -100,6 +102,7 @@ const NON_EMPTY_TEXT = /[^\s\u200B]/
100102
101103export const PromptInput : Component < PromptInputProps > = ( props ) => {
102104 const sdk = useSDK ( )
105+
103106 const sync = useSync ( )
104107 const local = useLocal ( )
105108 const files = useFile ( )
@@ -1249,6 +1252,14 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
12491252 }
12501253 }
12511254
1255+ const agentsQuery = useQuery ( ( ) => loadAgentsQuery ( sdk . directory ) )
1256+ const agentsLoading = ( ) => agentsQuery . isLoading
1257+
1258+ const globalProvidersQuery = useQuery ( ( ) => loadProvidersQuery ( null ) )
1259+ const providersQuery = useQuery ( ( ) => loadProvidersQuery ( sdk . directory ) )
1260+
1261+ const providersLoading = ( ) => agentsLoading ( ) || providersQuery . isLoading || globalProvidersQuery . isLoading
1262+
12521263 return (
12531264 < div class = "relative size-full _max-h-[320px] flex flex-col gap-0" >
12541265 < PromptPopover
@@ -1444,53 +1455,89 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
14441455 < span class = "truncate text-13-medium text-text-strong" > { language . t ( "prompt.mode.shell" ) } </ span >
14451456 < div class = "size-4 shrink-0" />
14461457 </ div >
1447- < div class = "flex items-center gap-1.5 min-w-0 flex-1" >
1448- < div data-component = "prompt-agent-control" >
1449- < TooltipKeybind
1450- placement = "top"
1451- gutter = { 4 }
1452- title = { language . t ( "command.agent.cycle" ) }
1453- keybind = { command . keybind ( "agent.cycle" ) }
1454- >
1455- < Select
1456- size = "normal"
1457- options = { agentNames ( ) }
1458- current = { local . agent . current ( ) ?. name ?? "" }
1459- onSelect = { ( value ) => {
1460- local . agent . set ( value )
1461- restoreFocus ( )
1462- } }
1463- class = "capitalize max-w-[160px] text-text-base"
1464- valueClass = "truncate text-13-regular text-text-base"
1465- triggerStyle = { control ( ) }
1466- triggerProps = { { "data-action" : "prompt-agent" } }
1467- variant = "ghost"
1468- />
1469- </ TooltipKeybind >
1470- </ div >
1471- < Show when = { store . mode !== "shell" } >
1472- < div data-component = "prompt-model-control" >
1473- < Show
1474- when = { providers . paid ( ) . length > 0 }
1475- fallback = {
1458+ < div class = "flex items-center gap-1.5 min-w-0 flex-1 h-7" >
1459+ < Show when = { ! agentsLoading ( ) } >
1460+ < div data-component = "prompt-agent-control" >
1461+ < TooltipKeybind
1462+ placement = "top"
1463+ gutter = { 4 }
1464+ title = { language . t ( "command.agent.cycle" ) }
1465+ keybind = { command . keybind ( "agent.cycle" ) }
1466+ >
1467+ < Select
1468+ size = "normal"
1469+ options = { agentNames ( ) }
1470+ current = { local . agent . current ( ) ?. name ?? "" }
1471+ onSelect = { ( value ) => {
1472+ local . agent . set ( value )
1473+ restoreFocus ( )
1474+ } }
1475+ class = "capitalize max-w-[160px] text-text-base"
1476+ valueClass = "truncate text-13-regular text-text-base"
1477+ triggerStyle = { control ( ) }
1478+ triggerProps = { { "data-action" : "prompt-agent" } }
1479+ variant = "ghost"
1480+ />
1481+ </ TooltipKeybind >
1482+ </ div >
1483+ </ Show >
1484+ < Show when = { ! providersLoading ( ) } >
1485+ < Show when = { store . mode !== "shell" } >
1486+ < div data-component = "prompt-model-control" >
1487+ < Show
1488+ when = { providers . paid ( ) . length > 0 }
1489+ fallback = {
1490+ < TooltipKeybind
1491+ placement = "top"
1492+ gutter = { 4 }
1493+ title = { language . t ( "command.model.choose" ) }
1494+ keybind = { command . keybind ( "model.choose" ) }
1495+ >
1496+ < Button
1497+ data-action = "prompt-model"
1498+ as = "div"
1499+ variant = "ghost"
1500+ size = "normal"
1501+ class = "min-w-0 max-w-[320px] text-13-regular text-text-base group"
1502+ style = { control ( ) }
1503+ onClick = { ( ) => {
1504+ void import ( "@/components/dialog-select-model-unpaid" ) . then ( ( x ) => {
1505+ dialog . show ( ( ) => < x . DialogSelectModelUnpaid model = { local . model } /> )
1506+ } )
1507+ } }
1508+ >
1509+ < Show when = { local . model . current ( ) ?. provider ?. id } >
1510+ < ProviderIcon
1511+ id = { local . model . current ( ) ?. provider ?. id ?? "" }
1512+ class = "size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150"
1513+ style = { { "will-change" : "opacity" , transform : "translateZ(0)" } }
1514+ />
1515+ </ Show >
1516+ < span class = "truncate" >
1517+ { local . model . current ( ) ?. name ?? language . t ( "dialog.model.select.title" ) }
1518+ </ span >
1519+ < Icon name = "chevron-down" size = "small" class = "shrink-0" />
1520+ </ Button >
1521+ </ TooltipKeybind >
1522+ }
1523+ >
14761524 < TooltipKeybind
14771525 placement = "top"
14781526 gutter = { 4 }
14791527 title = { language . t ( "command.model.choose" ) }
14801528 keybind = { command . keybind ( "model.choose" ) }
14811529 >
1482- < Button
1483- data-action = "prompt-model"
1484- as = "div"
1485- variant = "ghost"
1486- size = "normal"
1487- class = "min-w-0 max-w-[320px] text-13-regular text-text-base group"
1488- style = { control ( ) }
1489- onClick = { ( ) => {
1490- void import ( "@/components/dialog-select-model-unpaid" ) . then ( ( x ) => {
1491- dialog . show ( ( ) => < x . DialogSelectModelUnpaid model = { local . model } /> )
1492- } )
1530+ < ModelSelectorPopover
1531+ model = { local . model }
1532+ triggerAs = { Button }
1533+ triggerProps = { {
1534+ variant : "ghost" ,
1535+ size : "normal" ,
1536+ style : control ( ) ,
1537+ class : "min-w-0 max-w-[320px] text-13-regular text-text-base group" ,
1538+ "data-action" : "prompt-model" ,
14931539 } }
1540+ onClose = { restoreFocus }
14941541 >
14951542 < Show when = { local . model . current ( ) ?. provider ?. id } >
14961543 < ProviderIcon
@@ -1503,67 +1550,35 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
15031550 { local . model . current ( ) ?. name ?? language . t ( "dialog.model.select.title" ) }
15041551 </ span >
15051552 < Icon name = "chevron-down" size = "small" class = "shrink-0" />
1506- </ Button >
1553+ </ ModelSelectorPopover >
15071554 </ TooltipKeybind >
1508- }
1509- >
1555+ </ Show >
1556+ </ div >
1557+ < div data-component = "prompt-variant-control" >
15101558 < TooltipKeybind
15111559 placement = "top"
15121560 gutter = { 4 }
1513- title = { language . t ( "command.model.choose " ) }
1514- keybind = { command . keybind ( "model.choose " ) }
1561+ title = { language . t ( "command.model.variant.cycle " ) }
1562+ keybind = { command . keybind ( "model.variant.cycle " ) }
15151563 >
1516- < ModelSelectorPopover
1517- model = { local . model }
1518- triggerAs = { Button }
1519- triggerProps = { {
1520- variant : "ghost" ,
1521- size : "normal" ,
1522- style : control ( ) ,
1523- class : "min-w-0 max-w-[320px] text-13-regular text-text-base group" ,
1524- "data-action" : "prompt-model" ,
1564+ < Select
1565+ size = "normal"
1566+ options = { variants ( ) }
1567+ current = { local . model . variant . current ( ) ?? "default" }
1568+ label = { ( x ) => ( x === "default" ? language . t ( "common.default" ) : x ) }
1569+ onSelect = { ( value ) => {
1570+ local . model . variant . set ( value === "default" ? undefined : value )
1571+ restoreFocus ( )
15251572 } }
1526- onClose = { restoreFocus }
1527- >
1528- < Show when = { local . model . current ( ) ?. provider ?. id } >
1529- < ProviderIcon
1530- id = { local . model . current ( ) ?. provider ?. id ?? "" }
1531- class = "size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150"
1532- style = { { "will-change" : "opacity" , transform : "translateZ(0)" } }
1533- />
1534- </ Show >
1535- < span class = "truncate" >
1536- { local . model . current ( ) ?. name ?? language . t ( "dialog.model.select.title" ) }
1537- </ span >
1538- < Icon name = "chevron-down" size = "small" class = "shrink-0" />
1539- </ ModelSelectorPopover >
1573+ class = "capitalize max-w-[160px] text-text-base"
1574+ valueClass = "truncate text-13-regular text-text-base"
1575+ triggerStyle = { control ( ) }
1576+ triggerProps = { { "data-action" : "prompt-model-variant" } }
1577+ variant = "ghost"
1578+ />
15401579 </ TooltipKeybind >
1541- </ Show >
1542- </ div >
1543- < div data-component = "prompt-variant-control" >
1544- < TooltipKeybind
1545- placement = "top"
1546- gutter = { 4 }
1547- title = { language . t ( "command.model.variant.cycle" ) }
1548- keybind = { command . keybind ( "model.variant.cycle" ) }
1549- >
1550- < Select
1551- size = "normal"
1552- options = { variants ( ) }
1553- current = { local . model . variant . current ( ) ?? "default" }
1554- label = { ( x ) => ( x === "default" ? language . t ( "common.default" ) : x ) }
1555- onSelect = { ( value ) => {
1556- local . model . variant . set ( value === "default" ? undefined : value )
1557- restoreFocus ( )
1558- } }
1559- class = "capitalize max-w-[160px] text-text-base"
1560- valueClass = "truncate text-13-regular text-text-base"
1561- triggerStyle = { control ( ) }
1562- triggerProps = { { "data-action" : "prompt-model-variant" } }
1563- variant = "ghost"
1564- />
1565- </ TooltipKeybind >
1566- </ div >
1580+ </ div >
1581+ </ Show >
15671582 </ Show >
15681583 </ div >
15691584 </ div >
0 commit comments