diff options
| author | Shoubhit Dash <[email protected]> | 2026-04-16 17:30:14 +0530 |
|---|---|---|
| committer | Shoubhit Dash <[email protected]> | 2026-04-16 17:30:14 +0530 |
| commit | 2e18a603f0ea24154908e748493fd4bfaa74fc00 (patch) | |
| tree | b723e00af2821b213573b16fa199b64babd5f1f5 /packages/app/src/components/prompt-input.tsx | |
| parent | 9819eb04614fd607cacb07d754052f1531a82331 (diff) | |
| parent | 7341718f9234b0cf3a8758c87e91d2006b71bff6 (diff) | |
| download | opencode-2e18a603f0ea24154908e748493fd4bfaa74fc00.tar.gz opencode-2e18a603f0ea24154908e748493fd4bfaa74fc00.zip | |
merge dev
Diffstat (limited to 'packages/app/src/components/prompt-input.tsx')
| -rw-r--r-- | packages/app/src/components/prompt-input.tsx | 230 |
1 files changed, 114 insertions, 116 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index eedbc91cf..156b0b3a4 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -35,7 +35,6 @@ import { useLanguage } from "@/context/language" import { usePlatform } from "@/context/platform" import { useSessionLayout } from "@/pages/session/session-layout" import { createSessionTabs } from "@/pages/session/helpers" -import { promptEnabled, promptProbe } from "@/testing/prompt" import { createTextFragment, getCursorPosition, setCursorPosition, setRangeEdge } from "./prompt-input/editor-dom" import { createPromptAttachments } from "./prompt-input/attachments" import { ACCEPTED_FILE_TYPES } from "./prompt-input/files" @@ -55,6 +54,8 @@ import { PromptImageAttachments } from "./prompt-input/image-attachments" import { PromptDragOverlay } from "./prompt-input/drag-overlay" import { promptPlaceholder } from "./prompt-input/placeholder" import { ImagePreview } from "@opencode-ai/ui/image-preview" +import { useQuery } from "@tanstack/solid-query" +import { loadAgentsQuery, loadProvidersQuery } from "@/context/global-sync/bootstrap" interface PromptInputProps { class?: string @@ -101,6 +102,7 @@ const NON_EMPTY_TEXT = /[^\s\u200B]/ export const PromptInput: Component<PromptInputProps> = (props) => { const sdk = useSDK() + const sync = useSync() const local = useLocal() const files = useFile() @@ -213,9 +215,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => { if (!view().reviewPanel.opened()) view().reviewPanel.open() layout.fileTree.setTab("all") const tab = files.tab(item.path) - tabs().open(tab) + void tabs().open(tab) tabs().setActive(tab) - Promise.resolve(files.load(item.path)).finally(() => queueCommentFocus()) + void Promise.resolve(files.load(item.path)).finally(() => queueCommentFocus()) } const recent = createMemo(() => { @@ -639,7 +641,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => { const handleSlashSelect = (cmd: SlashCommand | undefined) => { if (!cmd) return - promptProbe.select(cmd.id) closePopover() const images = imageAttachments() @@ -728,21 +729,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => { element?.scrollIntoView({ block: "nearest", behavior: "smooth" }) }) }) - - if (promptEnabled()) { - createEffect(() => { - promptProbe.set({ - popover: store.popover, - slash: { - active: slashActive() ?? null, - ids: slashFlat().map((cmd) => cmd.id), - }, - }) - }) - - onCleanup(() => promptProbe.clear()) - } - const selectPopoverActive = () => { if (store.popover === "at") { const items = atFlat() @@ -1156,7 +1142,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => { } if (working()) { - abort() + void abort() event.preventDefault() event.stopPropagation() return @@ -1222,7 +1208,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => { return } if (working()) { - abort() + void abort() event.preventDefault() } return @@ -1262,10 +1248,18 @@ export const PromptInput: Component<PromptInputProps> = (props) => { ) { return } - handleSubmit(event) + void handleSubmit(event) } } + const agentsQuery = useQuery(() => loadAgentsQuery(sdk.directory)) + const agentsLoading = () => agentsQuery.isLoading + + const globalProvidersQuery = useQuery(() => loadProvidersQuery(null)) + const providersQuery = useQuery(() => loadProvidersQuery(sdk.directory)) + + const providersLoading = () => agentsLoading() || providersQuery.isLoading || globalProvidersQuery.isLoading + return ( <div class="relative size-full _max-h-[320px] flex flex-col gap-0"> <PromptPopover @@ -1461,53 +1455,89 @@ export const PromptInput: Component<PromptInputProps> = (props) => { <span class="truncate text-13-medium text-text-strong">{language.t("prompt.mode.shell")}</span> <div class="size-4 shrink-0" /> </div> - <div class="flex items-center gap-1.5 min-w-0 flex-1"> - <div data-component="prompt-agent-control"> - <TooltipKeybind - placement="top" - gutter={4} - title={language.t("command.agent.cycle")} - keybind={command.keybind("agent.cycle")} - > - <Select - size="normal" - options={agentNames()} - current={local.agent.current()?.name ?? ""} - onSelect={(value) => { - local.agent.set(value) - restoreFocus() - }} - class="capitalize max-w-[160px] text-text-base" - valueClass="truncate text-13-regular text-text-base" - triggerStyle={control()} - triggerProps={{ "data-action": "prompt-agent" }} - variant="ghost" - /> - </TooltipKeybind> - </div> - <Show when={store.mode !== "shell"}> - <div data-component="prompt-model-control"> - <Show - when={providers.paid().length > 0} - fallback={ + <div class="flex items-center gap-1.5 min-w-0 flex-1 h-7"> + <Show when={!agentsLoading()}> + <div data-component="prompt-agent-control"> + <TooltipKeybind + placement="top" + gutter={4} + title={language.t("command.agent.cycle")} + keybind={command.keybind("agent.cycle")} + > + <Select + size="normal" + options={agentNames()} + current={local.agent.current()?.name ?? ""} + onSelect={(value) => { + local.agent.set(value) + restoreFocus() + }} + class="capitalize max-w-[160px] text-text-base" + valueClass="truncate text-13-regular text-text-base" + triggerStyle={control()} + triggerProps={{ "data-action": "prompt-agent" }} + variant="ghost" + /> + </TooltipKeybind> + </div> + </Show> + <Show when={!providersLoading()}> + <Show when={store.mode !== "shell"}> + <div data-component="prompt-model-control"> + <Show + when={providers.paid().length > 0} + fallback={ + <TooltipKeybind + placement="top" + gutter={4} + title={language.t("command.model.choose")} + keybind={command.keybind("model.choose")} + > + <Button + data-action="prompt-model" + as="div" + variant="ghost" + size="normal" + class="min-w-0 max-w-[320px] text-13-regular text-text-base group" + style={control()} + onClick={() => { + void import("@/components/dialog-select-model-unpaid").then((x) => { + dialog.show(() => <x.DialogSelectModelUnpaid model={local.model} />) + }) + }} + > + <Show when={local.model.current()?.provider?.id}> + <ProviderIcon + id={local.model.current()?.provider?.id ?? ""} + class="size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150" + style={{ "will-change": "opacity", transform: "translateZ(0)" }} + /> + </Show> + <span class="truncate"> + {local.model.current()?.name ?? language.t("dialog.model.select.title")} + </span> + <Icon name="chevron-down" size="small" class="shrink-0" /> + </Button> + </TooltipKeybind> + } + > <TooltipKeybind placement="top" gutter={4} title={language.t("command.model.choose")} keybind={command.keybind("model.choose")} > - <Button - data-action="prompt-model" - as="div" - variant="ghost" - size="normal" - class="min-w-0 max-w-[320px] text-13-regular text-text-base group" - style={control()} - onClick={() => { - void import("@/components/dialog-select-model-unpaid").then((x) => { - dialog.show(() => <x.DialogSelectModelUnpaid model={local.model} />) - }) + <ModelSelectorPopover + model={local.model} + triggerAs={Button} + triggerProps={{ + variant: "ghost", + size: "normal", + style: control(), + class: "min-w-0 max-w-[320px] text-13-regular text-text-base group", + "data-action": "prompt-model", }} + onClose={restoreFocus} > <Show when={local.model.current()?.provider?.id}> <ProviderIcon @@ -1520,67 +1550,35 @@ export const PromptInput: Component<PromptInputProps> = (props) => { {local.model.current()?.name ?? language.t("dialog.model.select.title")} </span> <Icon name="chevron-down" size="small" class="shrink-0" /> - </Button> + </ModelSelectorPopover> </TooltipKeybind> - } - > + </Show> + </div> + <div data-component="prompt-variant-control"> <TooltipKeybind placement="top" gutter={4} - title={language.t("command.model.choose")} - keybind={command.keybind("model.choose")} + title={language.t("command.model.variant.cycle")} + keybind={command.keybind("model.variant.cycle")} > - <ModelSelectorPopover - model={local.model} - triggerAs={Button} - triggerProps={{ - variant: "ghost", - size: "normal", - style: control(), - class: "min-w-0 max-w-[320px] text-13-regular text-text-base group", - "data-action": "prompt-model", + <Select + size="normal" + options={variants()} + current={local.model.variant.current() ?? "default"} + label={(x) => (x === "default" ? language.t("common.default") : x)} + onSelect={(value) => { + local.model.variant.set(value === "default" ? undefined : value) + restoreFocus() }} - onClose={restoreFocus} - > - <Show when={local.model.current()?.provider?.id}> - <ProviderIcon - id={local.model.current()?.provider?.id ?? ""} - class="size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150" - style={{ "will-change": "opacity", transform: "translateZ(0)" }} - /> - </Show> - <span class="truncate"> - {local.model.current()?.name ?? language.t("dialog.model.select.title")} - </span> - <Icon name="chevron-down" size="small" class="shrink-0" /> - </ModelSelectorPopover> + class="capitalize max-w-[160px] text-text-base" + valueClass="truncate text-13-regular text-text-base" + triggerStyle={control()} + triggerProps={{ "data-action": "prompt-model-variant" }} + variant="ghost" + /> </TooltipKeybind> - </Show> - </div> - <div data-component="prompt-variant-control"> - <TooltipKeybind - placement="top" - gutter={4} - title={language.t("command.model.variant.cycle")} - keybind={command.keybind("model.variant.cycle")} - > - <Select - size="normal" - options={variants()} - current={local.model.variant.current() ?? "default"} - label={(x) => (x === "default" ? language.t("common.default") : x)} - onSelect={(value) => { - local.model.variant.set(value === "default" ? undefined : value) - restoreFocus() - }} - class="capitalize max-w-[160px] text-text-base" - valueClass="truncate text-13-regular text-text-base" - triggerStyle={control()} - triggerProps={{ "data-action": "prompt-model-variant" }} - variant="ghost" - /> - </TooltipKeybind> - </div> + </div> + </Show> </Show> </div> </div> |
