@agent-native/toolkit 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/composer/ComposerPlusMenu.js +29 -19
- package/dist/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +4 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +2 -2
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +12 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +249 -162
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.spec.js +33 -1
- package/dist/composer/TiptapComposer.spec.js.map +1 -1
- package/dist/composer/index.d.ts +1 -0
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -0
- package/dist/composer/index.js.map +1 -1
- package/dist/composer/model-selection.d.ts +12 -0
- package/dist/composer/model-selection.d.ts.map +1 -0
- package/dist/composer/model-selection.js +31 -0
- package/dist/composer/model-selection.js.map +1 -0
- package/dist/composer/model-selection.spec.d.ts +2 -0
- package/dist/composer/model-selection.spec.d.ts.map +1 -0
- package/dist/composer/model-selection.spec.js +38 -0
- package/dist/composer/model-selection.spec.js.map +1 -0
- package/package.json +1 -1
- package/src/composer/ComposerPlusMenu.tsx +122 -65
- package/src/composer/PromptComposer.tsx +8 -0
- package/src/composer/TiptapComposer.spec.ts +46 -0
- package/src/composer/TiptapComposer.tsx +678 -412
- package/src/composer/index.ts +6 -0
- package/src/composer/model-selection.spec.ts +45 -0
- package/src/composer/model-selection.ts +51 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Skeleton } from "@agent-native/toolkit/ui/skeleton";
|
|
3
3
|
import { useComposer, useComposerRuntime } from "@assistant-ui/react";
|
|
4
|
-
import { IconArrowUp, IconCheck, IconChevronDown, IconChevronRight, IconBulb, IconClock, IconBolt, IconTool, IconX, IconClipboardList, IconKey, IconPencil, IconPlugConnected, } from "@tabler/icons-react";
|
|
4
|
+
import { IconArrowUp, IconCheck, IconChevronDown, IconChevronRight, IconBulb, IconClock, IconBolt, IconTool, IconX, IconClipboardList, IconKey, IconPencil, IconPlugConnected, IconHelpCircle, } from "@tabler/icons-react";
|
|
5
5
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
6
6
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
7
7
|
import StarterKit from "@tiptap/starter-kit";
|
|
8
8
|
import { useState, useRef, useEffect, useCallback, useImperativeHandle, useMemo, } from "react";
|
|
9
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
9
|
+
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger, } from "../ui/popover.js";
|
|
10
10
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
|
|
11
11
|
import { ComposerPlusMenu } from "./ComposerPlusMenu.js";
|
|
12
12
|
import { getComposerDraftKey } from "./draft-key.js";
|
|
@@ -14,6 +14,7 @@ import { FileReference } from "./extensions/FileReference.js";
|
|
|
14
14
|
import { MentionReference } from "./extensions/MentionReference.js";
|
|
15
15
|
import { SkillReference } from "./extensions/SkillReference.js";
|
|
16
16
|
import { MentionPopover } from "./MentionPopover.js";
|
|
17
|
+
import { isClaudeCodeAgentId, isLunaModel, resolvePreferredAgentModel, } from "./model-selection.js";
|
|
17
18
|
import { createPastedAttachmentFile, readClipboardPaste, shouldConvertClipboardToAttachment, } from "./pasted-text.js";
|
|
18
19
|
import { AGENT_CHAT_INSERT_REFERENCE_EVENT, AGENT_CHAT_INSERT_REFERENCE_MESSAGE_TYPE, DEFAULT_REASONING_EFFORT, formatPromptContextItems, getReasoningEffortOptionsForModel, reasoningEffortLabel, resolveReasoningEffortSelection, useComposerRuntimeAdapters, } from "./runtime-adapters.js";
|
|
19
20
|
import { useMentionSearch } from "./use-mention-search.js";
|
|
@@ -513,7 +514,7 @@ function ModeSelector({ mode, onChange, planModeDisabled = false, planModeDisabl
|
|
|
513
514
|
setOpen(false);
|
|
514
515
|
}, className: "flex w-full items-center gap-3 px-3 py-2 hover:bg-accent/50 text-start", children: [_jsx(IconPencil, { className: "h-4 w-4 shrink-0 text-muted-foreground" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("span", { className: "font-medium text-foreground text-[13px]", children: t("agentChat.plan.act", { defaultValue: "Act" }) }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: t("agentChat.composer.actDescription", {
|
|
515
516
|
defaultValue: "Use tools and make approved changes",
|
|
516
|
-
}) })] }), mode === "build" && (_jsx(IconCheck, { className: "
|
|
517
|
+
}) })] }), mode === "build" && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] }), _jsxs("button", { type: "button", disabled: planModeDisabled, title: planModeDisabled ? resolvedPlanModeDisabledReason : undefined, onClick: () => {
|
|
517
518
|
if (planModeDisabled)
|
|
518
519
|
return;
|
|
519
520
|
onChange("plan");
|
|
@@ -524,20 +525,48 @@ function ModeSelector({ mode, onChange, planModeDisabled = false, planModeDisabl
|
|
|
524
525
|
? resolvedPlanModeDisabledReason
|
|
525
526
|
: t("agentChat.composer.planDescription", {
|
|
526
527
|
defaultValue: "Read-only research and approval first",
|
|
527
|
-
}) })] }), mode === "plan" && !planModeDisabled && (_jsx(IconCheck, { className: "
|
|
528
|
+
}) })] }), mode === "plan" && !planModeDisabled && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] })] })] }));
|
|
528
529
|
}
|
|
529
530
|
const FRIENDLY_MODEL_NAMES = {
|
|
530
531
|
auto: "Default model",
|
|
531
532
|
"codex-cli": "Codex",
|
|
533
|
+
"claude-cli": "Claude Code",
|
|
534
|
+
"pi-cli": "Pi",
|
|
535
|
+
"opencode-cli": "OpenCode",
|
|
532
536
|
"claude-fable-5": "Fable 5",
|
|
533
537
|
"kimi-k2-5": "Kimi K2.5",
|
|
534
538
|
"deepseek-v3-1": "DeepSeek v3.1",
|
|
535
539
|
"z-ai/glm-5.2": "GLM 5.2",
|
|
536
540
|
};
|
|
541
|
+
const LOCAL_RUNTIME_ENGINES = new Set([
|
|
542
|
+
"codex-cli",
|
|
543
|
+
"claude-cli",
|
|
544
|
+
"pi-cli",
|
|
545
|
+
"opencode-cli",
|
|
546
|
+
]);
|
|
547
|
+
function isOpenAiModelId(model) {
|
|
548
|
+
const normalizedModel = model.toLowerCase();
|
|
549
|
+
return (normalizedModel.startsWith("gpt-") ||
|
|
550
|
+
normalizedModel.startsWith("openai/gpt-"));
|
|
551
|
+
}
|
|
552
|
+
export function isOpenAiModelProviderGroup(group) {
|
|
553
|
+
const engine = group.engine.toLowerCase();
|
|
554
|
+
const label = group.label.toLowerCase();
|
|
555
|
+
if (engine === "codex-cli") {
|
|
556
|
+
return group.models.some(isOpenAiModelId);
|
|
557
|
+
}
|
|
558
|
+
return (engine.includes("openai") ||
|
|
559
|
+
label.includes("openai") ||
|
|
560
|
+
group.models.some(isOpenAiModelId));
|
|
561
|
+
}
|
|
562
|
+
const HARNESS_AGENTS_DOCS_URL = "https://www.agent-native.com/docs/harness-agents";
|
|
537
563
|
export const MODEL_SELECTOR_POPOVER_STYLE = {
|
|
538
564
|
fontSize: 13,
|
|
539
565
|
maxHeight: "min(500px, var(--radix-popover-content-available-height, 500px))",
|
|
540
566
|
};
|
|
567
|
+
const MODEL_SELECTOR_POPOVER_CLASS = "box-border w-64 rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-lg outline-none";
|
|
568
|
+
const PICKER_HELP_BUTTON_CLASS = "flex size-3 shrink-0 items-center justify-center rounded text-muted-foreground/60 hover:text-foreground";
|
|
569
|
+
const PICKER_HELP_ICON_CLASS = "size-2";
|
|
541
570
|
export function shouldShowModelSelectorSkeleton(isLoading, engineCount) {
|
|
542
571
|
return isLoading && engineCount === 0;
|
|
543
572
|
}
|
|
@@ -712,21 +741,25 @@ function ModelCostTier({ model }) {
|
|
|
712
741
|
: tier === 2
|
|
713
742
|
? t("agentChat.composer.costMedium", { defaultValue: "Medium cost" })
|
|
714
743
|
: t("agentChat.composer.costHigher", { defaultValue: "Higher cost" });
|
|
715
|
-
return
|
|
744
|
+
return _jsx("span", { className: "sr-only", children: costLabel });
|
|
716
745
|
}
|
|
717
746
|
export function getComposerReasoningEffortOptions(model) {
|
|
718
747
|
return model === "auto"
|
|
719
748
|
? ["low", "medium", "high", "xhigh", "max"]
|
|
720
749
|
: getReasoningEffortOptionsForModel(model);
|
|
721
750
|
}
|
|
722
|
-
function ModelSelector({ model, effort, engines, agents, selectedAgent, showAutoModelOption = true, modelListLoading = false, onChange, onEffortChange, onAgentChange, providerConnectStatusEnabled = true, onConnectProvider, onConnectLocalRuntime, imageModel, }) {
|
|
751
|
+
function ModelSelector({ model, effort, engines, agents, selectedAgent, hostedHarness = false, showAutoModelOption = true, modelListLoading = false, open: controlledOpen, onChange, onEffortChange, onAgentChange, onModelSelectorOpenChange, providerConnectStatusEnabled = true, onConnectProvider, onConnectLocalRuntime, imageModel, }) {
|
|
723
752
|
const adapters = useComposerRuntimeAdapters();
|
|
724
753
|
const t = adapters.translate;
|
|
725
754
|
const reasoning = adapters.models?.reasoning;
|
|
726
755
|
const defaultEffort = reasoning?.defaultEffort ?? DEFAULT_REASONING_EFFORT;
|
|
727
|
-
const [
|
|
756
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
757
|
+
const open = controlledOpen ?? internalOpen;
|
|
758
|
+
const isClaudeCodeAgent = isClaudeCodeAgentId(selectedAgent);
|
|
728
759
|
const autoModelGroup = showAutoModelOption
|
|
729
|
-
?
|
|
760
|
+
? isClaudeCodeAgent
|
|
761
|
+
? undefined
|
|
762
|
+
: engines.find((group) => group.models.includes("auto"))
|
|
730
763
|
: undefined;
|
|
731
764
|
const providerGroups = useMemo(() => engines
|
|
732
765
|
.map((group) => ({
|
|
@@ -734,6 +767,52 @@ function ModelSelector({ model, effort, engines, agents, selectedAgent, showAuto
|
|
|
734
767
|
models: group.models.filter((candidate) => candidate !== "auto"),
|
|
735
768
|
}))
|
|
736
769
|
.filter((group) => group.models.length > 0), [engines]);
|
|
770
|
+
const isCodexAgent = selectedAgent === "codex" || selectedAgent === "codex-cli";
|
|
771
|
+
const modelProviderGroups = useMemo(() => {
|
|
772
|
+
const hasCodexLocalGroup = providerGroups.some((group) => group.engine === "codex-cli");
|
|
773
|
+
const groups = providerGroups.flatMap((group) => {
|
|
774
|
+
if (group.engine === "codex-cli") {
|
|
775
|
+
return isCodexAgent && isOpenAiModelProviderGroup(group) ? [group] : [];
|
|
776
|
+
}
|
|
777
|
+
if (isCodexAgent &&
|
|
778
|
+
hasCodexLocalGroup &&
|
|
779
|
+
group.engine === "ai-sdk:openai") {
|
|
780
|
+
return [];
|
|
781
|
+
}
|
|
782
|
+
if (LOCAL_RUNTIME_ENGINES.has(group.engine))
|
|
783
|
+
return [];
|
|
784
|
+
if (!isCodexAgent)
|
|
785
|
+
return [group];
|
|
786
|
+
if (!isOpenAiModelProviderGroup(group))
|
|
787
|
+
return [];
|
|
788
|
+
const isExplicitOpenAiProvider = group.engine.toLowerCase().includes("openai") ||
|
|
789
|
+
group.label.toLowerCase().includes("openai");
|
|
790
|
+
const models = isExplicitOpenAiProvider
|
|
791
|
+
? group.models
|
|
792
|
+
: group.models.filter(isOpenAiModelId);
|
|
793
|
+
return models.length > 0 ? [{ ...group, models }] : [];
|
|
794
|
+
});
|
|
795
|
+
if (!isClaudeCodeAgent)
|
|
796
|
+
return groups;
|
|
797
|
+
return groups
|
|
798
|
+
.map((group) => ({
|
|
799
|
+
...group,
|
|
800
|
+
models: group.models.filter((candidate) => !isLunaModel(candidate)),
|
|
801
|
+
}))
|
|
802
|
+
.filter((group) => group.models.length > 0);
|
|
803
|
+
}, [isClaudeCodeAgent, isCodexAgent, providerGroups]);
|
|
804
|
+
const preferredAgentModel = useMemo(() => resolvePreferredAgentModel(selectedAgent, providerGroups), [providerGroups, selectedAgent]);
|
|
805
|
+
useEffect(() => {
|
|
806
|
+
if (!isClaudeCodeAgent || !isLunaModel(model) || !preferredAgentModel) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
if (preferredAgentModel.model === model &&
|
|
810
|
+
preferredAgentModel.engine ===
|
|
811
|
+
engines.find((group) => group.models.includes(model))?.engine) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
onChange(preferredAgentModel.model, preferredAgentModel.engine);
|
|
815
|
+
}, [engines, isClaudeCodeAgent, model, onChange, preferredAgentModel]);
|
|
737
816
|
const effortOptions = reasoning?.getOptionsForModel?.(model) ??
|
|
738
817
|
getComposerReasoningEffortOptions(model);
|
|
739
818
|
const selectedEffort = reasoning?.resolve?.(model, effort) ??
|
|
@@ -741,180 +820,188 @@ function ModelSelector({ model, effort, engines, agents, selectedAgent, showAuto
|
|
|
741
820
|
const effortLabel = useCallback((value) => localizedReasoningEffortLabel(t, value, (reasoning?.label ?? reasoningEffortLabel)(value)), [reasoning?.label, t]);
|
|
742
821
|
const selectedAgentOption = agents?.find((agent) => agent.id === (selectedAgent ?? "default"));
|
|
743
822
|
const selectedAgentLabel = selectedAgentOption?.label ?? "Default";
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
if (open) {
|
|
756
|
-
setExpandedGroups(new Set(selectedGroupKey ? [selectedGroupKey] : []));
|
|
757
|
-
}
|
|
758
|
-
}, [open, selectedGroupKey]);
|
|
759
|
-
const toggleGroup = useCallback((key) => {
|
|
760
|
-
setExpandedGroups((prev) => {
|
|
761
|
-
const next = new Set(prev);
|
|
762
|
-
if (next.has(key))
|
|
763
|
-
next.delete(key);
|
|
764
|
-
else
|
|
765
|
-
next.add(key);
|
|
766
|
-
return next;
|
|
767
|
-
});
|
|
768
|
-
}, []);
|
|
769
|
-
// The effort list is collapsed by default — it's a secondary
|
|
770
|
-
// control most users don't touch, so it stays tucked behind a header that
|
|
771
|
-
// reveals the current effort at a glance. Reset to collapsed on each open.
|
|
772
|
-
const [effortExpanded, setEffortExpanded] = useState(false);
|
|
773
|
-
useEffect(() => {
|
|
774
|
-
if (open)
|
|
775
|
-
setEffortExpanded(false);
|
|
776
|
-
}, [open]);
|
|
777
|
-
// The optional image-model section follows the same collapsed-by-default
|
|
778
|
-
// pattern; the current selection shows next to the header.
|
|
779
|
-
const [imageExpanded, setImageExpanded] = useState(false);
|
|
780
|
-
useEffect(() => {
|
|
781
|
-
if (open)
|
|
782
|
-
setImageExpanded(false);
|
|
783
|
-
}, [open]);
|
|
784
|
-
const imageModelLabel = imageModel?.options.find((option) => option.value === imageModel.value)
|
|
785
|
-
?.label ?? imageModel?.value;
|
|
823
|
+
const selectedModelLabel = friendlyModelName(model, t).replace(/^GPT-/, "");
|
|
824
|
+
const [detailSection, setDetailSection] = useState(null);
|
|
825
|
+
const resolvedSection = detailSection ?? "model";
|
|
826
|
+
const setPickerOpen = useCallback((nextOpen) => {
|
|
827
|
+
if (controlledOpen === undefined)
|
|
828
|
+
setInternalOpen(nextOpen);
|
|
829
|
+
if (nextOpen)
|
|
830
|
+
setDetailSection(null);
|
|
831
|
+
onModelSelectorOpenChange?.(nextOpen);
|
|
832
|
+
}, [controlledOpen, onModelSelectorOpenChange]);
|
|
833
|
+
const visibleProviderGroups = modelProviderGroups;
|
|
786
834
|
const showModelListSkeleton = shouldShowModelSelectorSkeleton(modelListLoading, engines.length);
|
|
787
|
-
//
|
|
788
|
-
//
|
|
789
|
-
//
|
|
835
|
+
// Keep setup actions beside model choices while any visible provider still
|
|
836
|
+
// needs configuration. The model rows remain visible so the user can see
|
|
837
|
+
// what becomes available after connecting or adding a key.
|
|
790
838
|
const builderFlow = adapters.builder.useConnectFlow({
|
|
791
839
|
enabled: providerConnectStatusEnabled,
|
|
792
840
|
trackingSource: "composer_builder_cta",
|
|
793
841
|
});
|
|
794
842
|
const hasConfiguredBuilderModels = providerGroups.some((group) => group.engine === "builder" && group.configured);
|
|
795
843
|
const hasConnectedSubscription = providerGroups.some((group) => group.configured && group.isSubscription);
|
|
796
|
-
const
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
844
|
+
const hasUnconfiguredVisibleModels = modelProviderGroups.some((group) => !group.configured);
|
|
845
|
+
const showBuilderAction = hasUnconfiguredVisibleModels &&
|
|
846
|
+
(Boolean(onConnectProvider) ||
|
|
847
|
+
(providerConnectStatusEnabled &&
|
|
848
|
+
!builderFlow.configured &&
|
|
849
|
+
!builderFlow.envManaged &&
|
|
850
|
+
!hasConfiguredBuilderModels &&
|
|
851
|
+
!hasConnectedSubscription));
|
|
852
|
+
const showAddKeysAction = hasUnconfiguredVisibleModels;
|
|
853
|
+
const showProviderActions = showBuilderAction || showAddKeysAction;
|
|
854
|
+
const onlyConnectPathAvailable = shouldShowOnlyConnectPath(showBuilderAction, providerGroups) &&
|
|
855
|
+
modelProviderGroups.length === 0;
|
|
803
856
|
const openLlmSettings = useCallback(() => {
|
|
804
857
|
try {
|
|
805
858
|
window.location.hash = "llm";
|
|
806
859
|
}
|
|
807
860
|
catch { }
|
|
808
861
|
window.dispatchEvent(new CustomEvent("agent-panel:open-settings"));
|
|
809
|
-
|
|
810
|
-
}, []);
|
|
862
|
+
setPickerOpen(false);
|
|
863
|
+
}, [setPickerOpen]);
|
|
811
864
|
const connectLocalRuntime = useCallback((engine) => {
|
|
812
865
|
onConnectLocalRuntime?.(engine);
|
|
813
|
-
|
|
814
|
-
}, [onConnectLocalRuntime]);
|
|
815
|
-
return (_jsxs(Popover, { open: open, onOpenChange:
|
|
866
|
+
setPickerOpen(false);
|
|
867
|
+
}, [onConnectLocalRuntime, setPickerOpen]);
|
|
868
|
+
return (_jsxs(Popover, { open: open, onOpenChange: setPickerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", "data-agent-composer-slot": "model-button", "aria-label": `${t("agentChat.composer.model", {
|
|
816
869
|
defaultValue: "Model",
|
|
817
870
|
})}: ${friendlyModelName(model, t)}${effortOptions.length > 0
|
|
818
|
-
? `. ${t("agentChat.composer.
|
|
819
|
-
defaultValue: "
|
|
871
|
+
? `. ${t("agentChat.composer.effort", {
|
|
872
|
+
defaultValue: "Effort",
|
|
820
873
|
})}: ${effortLabel(selectedEffort)}`
|
|
821
874
|
: ""}${selectedAgentOption && selectedAgentOption.id !== "default"
|
|
822
875
|
? `. Agent: ${selectedAgentLabel}`
|
|
823
876
|
: ""}`, className: "agent-composer-model-button flex min-w-0 max-w-[10.5rem] shrink items-center gap-1 rounded-md px-2 py-1 text-[12px] font-medium text-muted-foreground hover:bg-accent/50 hover:text-foreground", children: [_jsx("span", { className: "min-w-0 truncate", children: selectedAgentOption && selectedAgentOption.id !== "default"
|
|
824
877
|
? selectedAgentLabel
|
|
825
|
-
: compactComposerModelName(model, t) }), effortOptions.length > 0 && (_jsxs("span", { className: "agent-composer-model-effort min-w-0 shrink truncate text-muted-foreground/70", children: ["\u00B7 ", compactComposerReasoningEffortLabel(selectedEffort, t)] })), _jsx(IconChevronDown, { className: "h-3 w-3 shrink-0 opacity-60" })] }) }),
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
}, children:
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
?
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
878
|
+
: compactComposerModelName(model, t) }), effortOptions.length > 0 && (_jsxs("span", { className: "agent-composer-model-effort min-w-0 shrink truncate text-muted-foreground/70", children: ["\u00B7 ", compactComposerReasoningEffortLabel(selectedEffort, t)] })), _jsx(IconChevronDown, { className: "h-3 w-3 shrink-0 opacity-60" })] }) }), _jsx(PopoverContent, { side: "top", align: "end", sideOffset: 6, collisionPadding: 8, "data-agent-native-composer-popover": "true", className: `z-[260] overflow-visible ${MODEL_SELECTOR_POPOVER_CLASS}`, style: MODEL_SELECTOR_POPOVER_STYLE, children: _jsxs(Popover, { open: detailSection !== null, onOpenChange: () => undefined, children: [_jsx(PopoverAnchor, { asChild: true, children: _jsxs("div", { className: "flex flex-col", role: "tablist", "aria-label": t("agentChat.composer.pickerSections", {
|
|
879
|
+
defaultValue: "Picker sections",
|
|
880
|
+
}), children: [agents && agents.length > 0 && (_jsxs("button", { type: "button", role: "tab", "aria-selected": resolvedSection === "agent", onClick: () => setDetailSection("agent"), onMouseEnter: () => setDetailSection("agent"), className: `flex w-full min-w-0 items-center gap-1 rounded-md px-2 py-2 text-start transition-colors ${resolvedSection === "agent"
|
|
881
|
+
? "bg-accent text-foreground"
|
|
882
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"}`, children: [_jsxs("span", { className: "flex min-w-0 items-center", children: [_jsx("span", { className: "shrink-0 text-[12px] font-medium", children: "Agent" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { role: "img", "aria-label": t("agentChat.composer.harnessAgentHelp", {
|
|
883
|
+
defaultValue: "Learn about harness agents",
|
|
884
|
+
}), onClick: (event) => event.stopPropagation(), className: `ms-1.5 ${PICKER_HELP_BUTTON_CLASS}`, children: _jsx(IconHelpCircle, { "aria-hidden": "true", className: PICKER_HELP_ICON_CLASS, strokeWidth: 1.8 }) }) }), _jsxs(TooltipContent, { side: "right", className: "z-[400] max-w-xs", children: [_jsx("span", { className: "block", children: hostedHarness
|
|
885
|
+
? t("agentChat.composer.hostedHarnessDescription", {
|
|
886
|
+
defaultValue: "Hosted mode uses app tools only. For full coding with a repository and shell, use Agent Native Desktop.",
|
|
887
|
+
})
|
|
888
|
+
: t("agentChat.composer.harnessAgentDescription", {
|
|
889
|
+
defaultValue: "Harnesses run their own coding loop and local tools.",
|
|
890
|
+
}) }), _jsx("a", { href: HARNESS_AGENTS_DOCS_URL, target: "_blank", rel: "noreferrer", className: "mt-1 block underline underline-offset-2 hover:no-underline", children: t("agentChat.composer.learnMoreHarnessAgents", {
|
|
891
|
+
defaultValue: "Learn more about harness agents",
|
|
892
|
+
}) })] })] })] }), _jsx("span", { className: "ms-auto min-w-0 max-w-[6rem] truncate text-end text-[11px] text-muted-foreground/80", children: selectedAgentLabel }), _jsx(IconChevronRight, { className: "h-3 w-3 shrink-0 opacity-60 rtl:-scale-x-100" })] })), _jsxs("button", { type: "button", role: "tab", "aria-selected": resolvedSection === "model", onClick: () => setDetailSection("model"), onMouseEnter: () => setDetailSection("model"), className: `flex w-full min-w-0 items-center gap-1 rounded-md px-2 py-2 text-start transition-colors ${resolvedSection === "model"
|
|
893
|
+
? "bg-accent text-foreground"
|
|
894
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"}`, children: [_jsx("span", { className: "shrink-0 text-[12px] font-medium", children: "Model" }), _jsx("span", { className: "ms-auto min-w-0 max-w-[6rem] truncate text-end text-[11px] text-muted-foreground/80", children: selectedModelLabel }), _jsx(IconChevronRight, { className: "h-3 w-3 shrink-0 opacity-60 rtl:-scale-x-100" })] }), effortOptions.length > 0 && (_jsxs("button", { type: "button", role: "tab", "aria-selected": resolvedSection === "effort", onClick: () => setDetailSection("effort"), onMouseEnter: () => setDetailSection("effort"), className: `flex w-full min-w-0 items-center gap-1 rounded-md px-2 py-2 text-start transition-colors ${resolvedSection === "effort"
|
|
895
|
+
? "bg-accent text-foreground"
|
|
896
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"}`, children: [_jsx("span", { className: "shrink-0 text-[12px] font-medium", children: t("agentChat.composer.effort", {
|
|
897
|
+
defaultValue: "Effort",
|
|
898
|
+
}) }), _jsx("span", { className: "ms-auto min-w-0 max-w-[6rem] truncate text-end text-[11px] text-muted-foreground/80", children: effortLabel(selectedEffort) }), _jsx(IconChevronRight, { className: "h-3 w-3 shrink-0 opacity-60 rtl:-scale-x-100" })] }))] }) }), _jsx(PopoverContent, { side: "right", align: "start", sideOffset: 4, alignOffset: -8, collisionPadding: 8, className: `z-[320] overflow-visible ${MODEL_SELECTOR_POPOVER_CLASS}`, style: MODEL_SELECTOR_POPOVER_STYLE, children: _jsx("div", { className: "max-h-[min(500px,var(--radix-popover-content-available-height,500px))] overflow-y-auto", children: _jsxs("div", { className: "min-h-0 min-w-0", role: "tabpanel", "aria-label": resolvedSection, children: [resolvedSection === "agent" && agents && (_jsx("div", { className: "flex flex-col", children: agents.map((agent) => {
|
|
899
|
+
const isSelected = agent.id === (selectedAgent ?? "default");
|
|
900
|
+
const isConfigured = agent.configured !== false;
|
|
901
|
+
const canConnect = !isConfigured && Boolean(onConnectLocalRuntime);
|
|
902
|
+
const statusLabel = agent.statusLabel ??
|
|
903
|
+
(!isConfigured ? "Unavailable" : undefined);
|
|
904
|
+
return (_jsxs("div", { className: "group flex items-center rounded-md hover:bg-accent/30", children: [_jsxs("button", { type: "button", disabled: !isConfigured || !onAgentChange, "aria-current": isSelected ? "true" : undefined, onClick: () => {
|
|
905
|
+
if (!isConfigured)
|
|
906
|
+
return;
|
|
907
|
+
onAgentChange?.(agent.id);
|
|
908
|
+
setPickerOpen(false);
|
|
909
|
+
}, className: `flex min-w-0 flex-1 items-center gap-0.5 px-2 py-2 text-start ${isConfigured
|
|
910
|
+
? "hover:bg-accent/50"
|
|
911
|
+
: "cursor-default opacity-50"}`, children: [_jsx("span", { className: `min-w-0 truncate text-[12px] ${isSelected
|
|
912
|
+
? "text-foreground"
|
|
913
|
+
: "text-muted-foreground"}`, children: agent.label }), agent.description && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { role: "img", "aria-label": `${agent.label} details`, onClick: (event) => event.stopPropagation(), className: PICKER_HELP_BUTTON_CLASS, children: _jsx(IconHelpCircle, { "aria-hidden": "true", className: PICKER_HELP_ICON_CLASS, strokeWidth: 1.8 }) }) }), _jsx(TooltipContent, { side: "left", className: "z-[400] max-w-xs", children: agent.description })] })), _jsx("span", { className: "min-w-0 flex-1", "aria-hidden": "true" }), isSelected && isConfigured && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] }), !isConfigured && statusLabel && (_jsx("button", { type: "button", disabled: !canConnect, className: "ms-auto max-w-[6rem] shrink-0 truncate px-2 py-2 text-end text-[10px] text-muted-foreground/70 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 hover:text-foreground focus-visible:opacity-100 disabled:cursor-default", onClick: () => {
|
|
914
|
+
if (canConnect)
|
|
915
|
+
connectLocalRuntime(agent.id);
|
|
916
|
+
}, children: statusLabel }))] }, agent.id));
|
|
917
|
+
}) })), resolvedSection === "model" && (_jsxs(_Fragment, { children: [showProviderActions && (_jsxs(_Fragment, { children: [showBuilderAction && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => {
|
|
918
|
+
if (onConnectProvider) {
|
|
919
|
+
onConnectProvider();
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
builderFlow.start();
|
|
923
|
+
}
|
|
924
|
+
}, disabled: !onConnectProvider && builderFlow.connecting, className: "flex w-full items-start gap-2 rounded-md px-2 py-2 text-start hover:bg-accent/50 disabled:opacity-60", children: [_jsx(IconPlugConnected, { className: "mt-0.5 h-4 w-4 shrink-0 text-primary" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[12px] font-medium text-foreground", children: !onConnectProvider && builderFlow.connecting
|
|
925
|
+
? t("agentPanel.connectingBuilder", {
|
|
926
|
+
defaultValue: "Connecting Builder.io…",
|
|
927
|
+
})
|
|
928
|
+
: t("agentPanel.connectBuilderIo", {
|
|
929
|
+
defaultValue: "Connect Builder.io",
|
|
930
|
+
}) }), _jsx("span", { className: "block text-[11px] text-muted-foreground", children: t("agentPanel.builderModelCredits", {
|
|
931
|
+
defaultValue: "Free credits for Claude, OpenAI & Gemini",
|
|
932
|
+
}) })] })] }), !onConnectProvider && builderFlow.error && (_jsx("p", { role: "alert", className: "px-2 pb-2 ps-8 text-[11px] text-destructive", children: builderFlow.error }))] })), showAddKeysAction && (_jsxs("button", { type: "button", onClick: openLlmSettings, className: "flex w-full items-start gap-2 rounded-md px-2 py-2 text-start hover:bg-accent/50", children: [_jsx(IconKey, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[12px] font-medium text-foreground", children: t("agentPanel.addOwnKeys", {
|
|
933
|
+
defaultValue: "Add your own keys",
|
|
934
|
+
}) }), _jsx("span", { className: "block text-[11px] text-muted-foreground", children: t("agentPanel.configureProviderKeys", {
|
|
935
|
+
defaultValue: "Choose a cloud, gateway, or local provider",
|
|
936
|
+
}) })] })] }))] })), imageModel && imageModel.options.length > 0 && (_jsxs("div", { className: "mt-2 pt-1", children: [_jsx("div", { className: "px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: imageModel.label ??
|
|
937
|
+
t("agentChat.composer.imageModel", {
|
|
938
|
+
defaultValue: "Image model",
|
|
939
|
+
}) }), imageModel.options.map((option) => (_jsxs("button", { type: "button", onClick: () => {
|
|
940
|
+
imageModel.onChange(option.value);
|
|
941
|
+
setPickerOpen(false);
|
|
942
|
+
}, className: "flex w-full items-center gap-3 rounded-md px-2 py-2 text-start hover:bg-accent/50", children: [_jsx("span", { className: `min-w-0 flex-1 truncate text-[12px] ${option.value === imageModel.value
|
|
943
|
+
? "text-foreground"
|
|
944
|
+
: "text-muted-foreground"}`, children: option.label }), option.value === imageModel.value && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] }, option.value)))] })), showModelListSkeleton && _jsx(ModelSelectorSkeleton, {}), isCodexAgent &&
|
|
945
|
+
!showModelListSkeleton &&
|
|
946
|
+
!onlyConnectPathAvailable &&
|
|
947
|
+
modelProviderGroups.length === 0 && (_jsxs("button", { type: "button", onClick: openLlmSettings, className: "flex w-full items-center rounded-md px-2 py-2 text-start hover:bg-accent/50", children: [_jsx("span", { className: "min-w-0 flex-1 truncate text-[12px] text-muted-foreground", children: t("agentChat.composer.noOpenAiModels", {
|
|
948
|
+
defaultValue: "No OpenAI models configured",
|
|
949
|
+
}) }), _jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground/70", children: "Configure" })] })), autoModelGroup && !onlyConnectPathAvailable && (_jsxs("button", { type: "button", onClick: () => {
|
|
950
|
+
onChange("auto", autoModelGroup.engine);
|
|
951
|
+
setPickerOpen(false);
|
|
952
|
+
}, className: "mt-1 flex w-full items-center gap-3 rounded-md px-2 py-1.5 text-start hover:bg-accent/50", children: [_jsx("span", { className: `min-w-0 flex-1 truncate text-[13px] ${model === "auto"
|
|
953
|
+
? "text-foreground"
|
|
954
|
+
: "text-muted-foreground"}`, children: t("agentChat.composer.auto", {
|
|
955
|
+
defaultValue: "Auto",
|
|
956
|
+
}) }), model === "auto" && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] })), !onlyConnectPathAvailable &&
|
|
957
|
+
visibleProviderGroups.map((group, groupIndex) => {
|
|
958
|
+
const models = latestModelsOnly(group.models);
|
|
959
|
+
const showProviderLabels = visibleProviderGroups.length > 1;
|
|
960
|
+
const isLocalRuntime = group.engine === "codex-cli" ||
|
|
961
|
+
group.engine === "claude-cli";
|
|
962
|
+
const canConnectLocalRuntime = isLocalRuntime && Boolean(onConnectLocalRuntime);
|
|
963
|
+
const statusLabel = group.statusLabel ??
|
|
964
|
+
(!group.configured
|
|
965
|
+
? canConnectLocalRuntime
|
|
966
|
+
? t("agentChat.auth.logIn", {
|
|
967
|
+
defaultValue: "Sign in",
|
|
968
|
+
})
|
|
969
|
+
: t("agentChat.composer.needsApiKey", {
|
|
970
|
+
defaultValue: "needs API key",
|
|
971
|
+
})
|
|
972
|
+
: undefined);
|
|
973
|
+
return (_jsxs("div", { className: showProviderLabels && groupIndex > 0
|
|
974
|
+
? "mt-2 pt-1"
|
|
975
|
+
: "", children: [showProviderLabels && (_jsxs("div", { className: "group flex items-center px-2 py-1", children: [_jsx("span", { className: "shrink-0 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: group.label }), !group.configured && statusLabel && (_jsx("button", { type: "button", "aria-label": statusLabel, className: "ms-auto max-w-[9rem] shrink-0 cursor-pointer truncate px-0 py-1 text-end text-[10px] text-muted-foreground/60 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 hover:text-foreground focus-visible:opacity-100", onClick: () => canConnectLocalRuntime
|
|
976
|
+
? connectLocalRuntime(group.engine)
|
|
977
|
+
: openLlmSettings(), children: statusLabel })), group.configured && statusLabel && (_jsx("span", { className: "ms-auto max-w-[9rem] shrink-0 truncate py-1 text-end text-[10px] text-muted-foreground/70 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100", children: statusLabel }))] })), models.map((m) => {
|
|
978
|
+
const isSelected = m === model && group.configured;
|
|
979
|
+
return (_jsxs("button", { type: "button", onClick: () => {
|
|
980
|
+
if (!group.configured) {
|
|
981
|
+
if (canConnectLocalRuntime) {
|
|
982
|
+
connectLocalRuntime(group.engine);
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
openLlmSettings();
|
|
986
|
+
}
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
onChange(m, group.engine);
|
|
990
|
+
const nextOptions = getReasoningEffortOptionsForModel(m);
|
|
991
|
+
if (nextOptions.length > 0 &&
|
|
992
|
+
!nextOptions.includes(selectedEffort)) {
|
|
993
|
+
onEffortChange?.(defaultEffort);
|
|
994
|
+
}
|
|
995
|
+
setPickerOpen(false);
|
|
996
|
+
}, className: `group flex w-full items-center gap-3 rounded-md px-2 py-2 text-start ${group.configured
|
|
997
|
+
? "hover:bg-accent/50"
|
|
998
|
+
: "cursor-default opacity-40"}`, children: [_jsx("span", { className: `min-w-0 flex-1 truncate text-[12px] ${isSelected
|
|
999
|
+
? "text-foreground"
|
|
1000
|
+
: "text-muted-foreground"}`, children: friendlyModelName(m, t) }), _jsx(ModelCostTier, { model: m }), !showProviderLabels && statusLabel && (_jsx("span", { className: "hidden max-w-[9rem] shrink-0 truncate text-[10px] text-muted-foreground/70 group-hover:inline", children: statusLabel })), isSelected && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] }, m));
|
|
1001
|
+
})] }, `${group.engine}:${group.label}`));
|
|
1002
|
+
})] })), resolvedSection === "effort" && effortOptions.length > 0 && (_jsx("div", { className: "flex flex-col", children: effortOptions.map((option) => (_jsxs("button", { type: "button", onClick: () => onEffortChange?.(option), className: "flex w-full items-center gap-3 rounded-md px-2 py-2 text-start hover:bg-accent/50", children: [_jsx("span", { className: `min-w-0 flex-1 truncate text-[12px] ${option === selectedEffort
|
|
1003
|
+
? "text-foreground"
|
|
1004
|
+
: "text-muted-foreground"}`, children: effortLabel(option) }), option === selectedEffort && (_jsx(IconCheck, { className: "size-4 shrink-0 text-primary" }))] }, option))) }))] }) }) })] }) })] }));
|
|
918
1005
|
}
|
|
919
1006
|
function ModelSelectorSkeleton() {
|
|
920
1007
|
const t = useComposerRuntimeAdapters().translate;
|
|
@@ -924,7 +1011,7 @@ function ModelSelectorSkeleton() {
|
|
|
924
1011
|
defaultValue: "Loading models…",
|
|
925
1012
|
}) }), ["w-24", "w-32", "w-20", "w-28"].map((width, index) => (_jsxs("div", { className: "flex items-center gap-1.5 px-1 py-1.5", children: [_jsx(Skeleton, { className: "size-3 rounded-sm" }), _jsx(Skeleton, { className: `h-3 ${width}` })] }, index)))] }));
|
|
926
1013
|
}
|
|
927
|
-
export function TiptapComposer({ placeholder, disabled = false, maxDocumentAttachmentBytes = MAX_DOCUMENT_ATTACHMENT_BYTES, documentAttachmentLimitLabel = "PDFs", focusRef, initialText, initialTextKey, onSubmit, onBeforeSubmit, clearOnSubmit = true, onTextChange, actionButton, willQueue = false, extraActionButton, stopButton, attachButton, modeControl, toolbarSlot, layoutVariant = "default", slashCommands = [], slashSkills = [], includeDefaultSlashCommands = true, includeDefaultSlashSkills = true, onSlashCommand, execMode, onExecModeChange, planModeDisabled = false, planModeDisabledReason, voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED, selectedModel, selectedEffort, showAutoModelOption = true, availableModels, modelListLoading, onModelChange, onEffortChange, availableAgents, selectedAgent, onAgentChange, providerConnectStatusEnabled, onConnectProvider, onConnectLocalRuntime, imageModelMenu, draftScope, contextItems = [], onRemoveContextItem, plusMenuMode = "full", extensionTools = false, interceptBuildRequestsForBuilder = false, onAttachmentError, }) {
|
|
1014
|
+
export function TiptapComposer({ placeholder, disabled = false, maxDocumentAttachmentBytes = MAX_DOCUMENT_ATTACHMENT_BYTES, documentAttachmentLimitLabel = "PDFs", focusRef, initialText, initialTextKey, onSubmit, onBeforeSubmit, clearOnSubmit = true, onTextChange, actionButton, willQueue = false, extraActionButton, stopButton, attachButton, modeControl, toolbarSlot, layoutVariant = "default", slashCommands = [], slashSkills = [], includeDefaultSlashCommands = true, includeDefaultSlashSkills = true, onSlashCommand, execMode, onExecModeChange, planModeDisabled = false, planModeDisabledReason, voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED, selectedModel, selectedEffort, showAutoModelOption = true, modelSelectorOpen, availableModels, modelListLoading, onModelChange, onEffortChange, availableAgents, selectedAgent, hostedHarness, onAgentChange, onModelSelectorOpenChange, providerConnectStatusEnabled, onConnectProvider, onConnectLocalRuntime, imageModelMenu, draftScope, contextItems = [], onRemoveContextItem, plusMenuMode = "full", extensionTools = false, interceptBuildRequestsForBuilder = false, onAttachmentError, }) {
|
|
928
1015
|
const adapters = useComposerRuntimeAdapters();
|
|
929
1016
|
const t = adapters.translate;
|
|
930
1017
|
const sendButtonTooltip = t(getComposerSendTooltipKey(willQueue), {
|
|
@@ -2139,6 +2226,6 @@ export function TiptapComposer({ placeholder, disabled = false, maxDocumentAttac
|
|
|
2139
2226
|
defaultValue: "Remove {{name}} context",
|
|
2140
2227
|
name: item.title,
|
|
2141
2228
|
}), className: "ms-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(IconX, { className: "h-3 w-3" }) })] }, item.key)))] })), _jsx("div", { "data-agent-composer-variant": layoutVariant, "data-agent-composer-slot": "editor-wrap", className: `agent-composer-editor-wrap ${composerMode || hasContextRows ? "px-2 pt-1 pb-1" : "px-2 pt-2 pb-1"}`, children: _jsx(EditorContent, { editor: editor, "data-agent-composer-variant": layoutVariant, "data-agent-composer-slot": "editor", className: "agent-composer-editor aui-composer flex-1 min-w-0 [&_.ProseMirror]:outline-none [&_.ProseMirror_p]:m-0 px-0.5" }) }), voiceEnabled && _jsx(VoiceRecordingOverlay, { voice: voice }), _jsxs("div", { "data-agent-composer-variant": layoutVariant, "data-agent-composer-slot": "toolbar", className: "agent-composer-toolbar flex items-center gap-1 px-2 py-1.5", children: [attachButton ??
|
|
2142
|
-
(plusMenuMode === "hidden" ? null : (_jsx(ComposerPlusMenu, { onSelectMode: handleSelectMode, mode: plusMenuMode, extensionTools: extensionTools, onAttachmentError: onAttachmentError }))), toolbarSlot ?? modeControl, _jsx("div", { "data-agent-composer-slot": "toolbar-spacer", className: "flex-1" }), selectedModel && availableModels && onModelChange && (_jsx(ModelSelector, { model: selectedModel, effort: selectedEffort, engines: availableModels, agents: availableAgents, selectedAgent: selectedAgent, showAutoModelOption: showAutoModelOption, modelListLoading: modelListLoading, onChange: onModelChange, onEffortChange: onEffortChange, onAgentChange: onAgentChange, providerConnectStatusEnabled: providerConnectStatusEnabled, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, imageModel: imageModelMenu })), execMode && onExecModeChange && (_jsx(ModeSelector, { mode: execMode, onChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason })), actionButton ?? (_jsxs(_Fragment, { children: [extraActionButton, voiceEnabled && (_jsx(VoiceButton, { voice: voice, isMac: isMac, disabled: disabled })), primaryAction === "stop" ? (stopButton) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => void submitComposer("immediate"), disabled: !canSend, "data-agent-composer-slot": "send-button", className: "agent-composer-send-button shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-primary text-primary-foreground hover:opacity-90 transition-[opacity,transform] duration-150 active:scale-[0.97] disabled:opacity-30 disabled:cursor-not-allowed", children: _jsx(IconArrowUp, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: sendButtonTooltip })] }))] }))] }), _jsx(MentionPopover, { ref: popoverRef, type: popover?.type ?? "@", position: popover?.position ?? null, mentionItems: filteredMentionItems, skills: filteredSkills, commands: filteredCommands, hint: hint, isLoading: popover?.type === "@" ? mentionsLoading : skillsLoading, query: popover?.query ?? "", onSelectMention: handleSelectMention, onSelectSkill: handleSelectSkill, onSelectCommand: handleSelectCommand, onClose: closePopover })] }));
|
|
2229
|
+
(plusMenuMode === "hidden" ? null : (_jsx(ComposerPlusMenu, { onSelectMode: handleSelectMode, mode: plusMenuMode, extensionTools: extensionTools, onAttachmentError: onAttachmentError }))), toolbarSlot ?? modeControl, _jsx("div", { "data-agent-composer-slot": "toolbar-spacer", className: "flex-1" }), selectedModel && availableModels && onModelChange && (_jsx(ModelSelector, { model: selectedModel, open: modelSelectorOpen, effort: selectedEffort, engines: availableModels, agents: availableAgents, selectedAgent: selectedAgent, hostedHarness: hostedHarness, showAutoModelOption: showAutoModelOption, modelListLoading: modelListLoading, onChange: onModelChange, onEffortChange: onEffortChange, onAgentChange: onAgentChange, onModelSelectorOpenChange: onModelSelectorOpenChange, providerConnectStatusEnabled: providerConnectStatusEnabled, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, imageModel: imageModelMenu })), execMode && onExecModeChange && (_jsx(ModeSelector, { mode: execMode, onChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason })), actionButton ?? (_jsxs(_Fragment, { children: [extraActionButton, voiceEnabled && (_jsx(VoiceButton, { voice: voice, isMac: isMac, disabled: disabled })), primaryAction === "stop" ? (stopButton) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => void submitComposer("immediate"), disabled: !canSend, "data-agent-composer-slot": "send-button", className: "agent-composer-send-button shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-primary text-primary-foreground hover:opacity-90 transition-[opacity,transform] duration-150 active:scale-[0.97] disabled:opacity-30 disabled:cursor-not-allowed", children: _jsx(IconArrowUp, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: sendButtonTooltip })] }))] }))] }), _jsx(MentionPopover, { ref: popoverRef, type: popover?.type ?? "@", position: popover?.position ?? null, mentionItems: filteredMentionItems, skills: filteredSkills, commands: filteredCommands, hint: hint, isLoading: popover?.type === "@" ? mentionsLoading : skillsLoading, query: popover?.query ?? "", onSelectMention: handleSelectMention, onSelectSkill: handleSelectSkill, onSelectCommand: handleSelectCommand, onClose: closePopover })] }));
|
|
2143
2230
|
}
|
|
2144
2231
|
//# sourceMappingURL=TiptapComposer.js.map
|