@parallelworks/ui 0.41.0 → 0.43.0
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/README.md +25 -0
- package/dist/ai/components/AllocationSelector.d.ts +3 -4
- package/dist/ai/components/AllocationSelector.js +37 -33
- package/dist/ai/components/AttachmentManager.js +7 -7
- package/dist/ai/components/AttachmentUpload.js +5 -5
- package/dist/ai/components/BranchNavigator.js +1 -1
- package/dist/ai/components/ChatEmptyState.js +2 -2
- package/dist/ai/components/ChatInput.js +10 -8
- package/dist/ai/components/ChatLayout.js +4 -5
- package/dist/ai/components/ChatMessage.js +12 -12
- package/dist/ai/components/ChatMessageList.js +9 -9
- package/dist/ai/components/ChatSidebar.js +8 -9
- package/dist/ai/components/ChatThread.js +4 -4
- package/dist/ai/components/ComposerChrome.d.ts +2 -2
- package/dist/ai/components/ComposerChrome.js +3 -6
- package/dist/ai/components/DragOverlay.js +2 -2
- package/dist/ai/components/ModelSelector.d.ts +5 -3
- package/dist/ai/components/ModelSelector.js +102 -339
- package/dist/ai/components/PastedText.js +11 -11
- package/dist/ai/components/ProviderIssueBanner.d.ts +2 -0
- package/dist/ai/components/ProviderIssueBanner.js +34 -16
- package/dist/ai/components/Reasoning.js +4 -4
- package/dist/ai/components/ShareDialog.js +43 -35
- package/dist/ai/components/SlashMenu.d.ts +12 -2
- package/dist/ai/components/SlashMenu.js +29 -13
- package/dist/ai/components/agent/ActivityLine.js +3 -3
- package/dist/ai/components/agent/AgentMessageParts.js +20 -20
- package/dist/ai/components/agent/PermissionPicker.js +13 -11
- package/dist/ai/components/conversationActions.d.ts +4 -6
- package/dist/ai/components/conversationActions.js +9 -13
- package/dist/ai/core/ChatProvider.js +1 -1
- package/dist/ai/core/config.js +1 -1
- package/dist/ai/core/providerIssues.d.ts +7 -0
- package/dist/ai/core/providerIssues.js +9 -1
- package/dist/ai/core/useKeyboardShortcuts.d.ts +4 -0
- package/dist/ai/core/useKeyboardShortcuts.js +8 -2
- package/dist/ai/index.d.ts +0 -1
- package/dist/ai/index.js +1 -2
- package/dist/ai/strings.d.ts +19 -0
- package/dist/ai/strings.js +18 -1
- package/dist/ai/ui/Avatar.js +5 -5
- package/dist/ai/ui/ConversationSidebar.d.ts +0 -1
- package/dist/ai/ui/ConversationSidebar.js +6 -7
- package/dist/ai/ui/Markdown.js +3 -3
- package/dist/ai/ui/Notice.js +6 -6
- package/dist/ai/ui/chip.d.ts +4 -0
- package/dist/ai/ui/chip.js +8 -0
- package/dist/ai/ui/sidebar.d.ts +6 -5
- package/dist/ai/ui/sidebar.js +39 -43
- package/dist/components/ActionMenu.d.ts +13 -0
- package/dist/components/ActionMenu.js +30 -0
- package/dist/components/Avatar.js +6 -6
- package/dist/components/Breadcrumbs.js +1 -1
- package/dist/components/Button.js +10 -10
- package/dist/components/Callout.js +2 -2
- package/dist/components/Card.js +3 -3
- package/dist/components/Combobox.d.ts +49 -0
- package/dist/components/Combobox.js +405 -0
- package/dist/components/ConfirmModal.js +11 -11
- package/dist/components/ContextMenu.d.ts +23 -0
- package/dist/components/ContextMenu.js +89 -0
- package/dist/components/CopyToClipboard.js +2 -2
- package/dist/components/CreateModal.d.ts +19 -38
- package/dist/components/CreateModal.js +116 -267
- package/dist/components/DescriptionList.js +8 -8
- package/dist/components/Filter.js +2 -2
- package/dist/components/FilterPill.js +2 -2
- package/dist/components/HoverCard.d.ts +14 -0
- package/dist/components/HoverCard.js +33 -0
- package/dist/components/IconButton.d.ts +5 -5
- package/dist/components/IconButton.js +18 -22
- package/dist/components/InfoTip.d.ts +15 -0
- package/dist/components/InfoTip.js +60 -0
- package/dist/components/Input.js +5 -5
- package/dist/components/LetterBadge.js +2 -2
- package/dist/components/Loader.js +3 -3
- package/dist/components/Markdown.js +1 -1
- package/dist/components/MarkdownImpl.js +2 -2
- package/dist/components/Menu.d.ts +33 -0
- package/dist/components/Menu.js +86 -0
- package/dist/components/MenuEntries.d.ts +56 -0
- package/dist/components/MenuEntries.js +123 -0
- package/dist/components/Modal.d.ts +29 -0
- package/dist/components/Modal.js +47 -0
- package/dist/components/Overview.js +11 -10
- package/dist/components/PageHeader.d.ts +10 -16
- package/dist/components/PageHeader.js +69 -95
- package/dist/components/Pagination.js +5 -5
- package/dist/components/Provider.d.ts +5 -11
- package/dist/components/Provider.js +11 -14
- package/dist/components/Radio.d.ts +8 -0
- package/dist/components/Radio.js +16 -0
- package/dist/components/SectionHeader.js +2 -2
- package/dist/components/SegmentedControl.d.ts +6 -5
- package/dist/components/SegmentedControl.js +34 -30
- package/dist/components/Select.d.ts +27 -0
- package/dist/components/Select.js +78 -0
- package/dist/components/SettingModeOption.d.ts +5 -8
- package/dist/components/SettingModeOption.js +10 -12
- package/dist/components/SettingRow.js +4 -4
- package/dist/components/SettingsCard.js +4 -4
- package/dist/components/SettingsGroup.js +2 -2
- package/dist/components/Sort.js +1 -1
- package/dist/components/StatusBadge.js +7 -7
- package/dist/components/StatusIcons.js +4 -4
- package/dist/components/Switch.d.ts +22 -0
- package/dist/components/Switch.js +28 -0
- package/dist/components/Table.js +11 -11
- package/dist/components/Tooltip.d.ts +24 -20
- package/dist/components/Tooltip.js +58 -76
- package/dist/components/comboboxItems.d.ts +24 -0
- package/dist/components/comboboxItems.js +10 -0
- package/dist/components/floating.d.ts +14 -0
- package/dist/components/floating.js +21 -0
- package/dist/components/search.d.ts +2 -0
- package/dist/components/search.js +14 -0
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/EditorField.js +16 -21
- package/dist/editor/FormCodePanel.js +19 -19
- package/dist/editor/Monaco.js +3 -3
- package/dist/file-explorer/FileExplorer.js +77 -81
- package/dist/file-explorer/FileExplorerContext.js +2 -2
- package/dist/file-explorer/FilePreview/CodePreviewEditor.js +1 -1
- package/dist/file-explorer/FilePreview/Inline.js +1 -1
- package/dist/file-explorer/FilePreview/StreamedBadge.js +5 -6
- package/dist/file-explorer/FilePreview/Viewer.js +8 -8
- package/dist/file-explorer/FilePreview/index.d.ts +1 -1
- package/dist/file-explorer/FilePreview/index.js +49 -83
- package/dist/file-explorer/FileRow.d.ts +4 -3
- package/dist/file-explorer/FileRow.js +32 -38
- package/dist/file-explorer/FileRowsWindow.d.ts +3 -2
- package/dist/file-explorer/FileRowsWindow.js +4 -4
- package/dist/file-explorer/FileTable.d.ts +3 -2
- package/dist/file-explorer/FileTable.js +3 -3
- package/dist/file-explorer/LoadMoreRow.js +1 -1
- package/dist/file-explorer/TreeView.js +11 -16
- package/dist/file-explorer/helpers.js +11 -12
- package/dist/file-explorer/toasts.js +11 -11
- package/dist/form/FieldGroup.d.ts +11 -0
- package/dist/form/FieldGroup.js +36 -0
- package/dist/form/FieldWrapper.js +4 -4
- package/dist/form/Fields/BooleanField.js +23 -33
- package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
- package/dist/form/Fields/CheckboxGroupField.js +9 -13
- package/dist/form/Fields/ColorField.d.ts +1 -2
- package/dist/form/Fields/ColorField.js +6 -11
- package/dist/form/Fields/DropdownField.d.ts +3 -13
- package/dist/form/Fields/DropdownField.js +40 -27
- package/dist/form/Fields/DurationField.d.ts +1 -2
- package/dist/form/Fields/DurationField.js +25 -32
- package/dist/form/Fields/LabelField.js +2 -2
- package/dist/form/Fields/MultiDropdownField.d.ts +6 -12
- package/dist/form/Fields/MultiDropdownField.js +31 -22
- package/dist/form/Fields/NumberField.d.ts +1 -1
- package/dist/form/Fields/NumberField.js +65 -35
- package/dist/form/Fields/ObjectField.d.ts +1 -1
- package/dist/form/Fields/ObjectField.js +12 -43
- package/dist/form/Fields/RadioField.d.ts +1 -1
- package/dist/form/Fields/RadioField.js +30 -41
- package/dist/form/Fields/RangeField.d.ts +1 -2
- package/dist/form/Fields/RangeField.js +23 -16
- package/dist/form/Fields/StringField.d.ts +1 -2
- package/dist/form/Fields/StringField.js +58 -26
- package/dist/form/Fields/TextAreaField.js +12 -10
- package/dist/form/Form.d.ts +30 -48
- package/dist/form/Form.js +306 -412
- package/dist/form/FormLayout.js +9 -9
- package/dist/form/Wizard/WizardContainer.d.ts +1 -4
- package/dist/form/Wizard/WizardContainer.js +40 -56
- package/dist/form/Wizard/WizardNavigation.js +1 -1
- package/dist/form/Wizard/WizardStepContent.d.ts +1 -5
- package/dist/form/Wizard/WizardStepContent.js +11 -16
- package/dist/form/Wizard/WizardStepIndicator.js +6 -6
- package/dist/form/Wizard/types.d.ts +0 -14
- package/dist/form/fieldRegistry.d.ts +1 -1
- package/dist/form/fieldRegistry.js +6 -6
- package/dist/form/formEditing.js +1 -1
- package/dist/form/index.d.ts +5 -4
- package/dist/form/index.js +6 -7
- package/dist/form/lib.js +3 -2
- package/dist/form/types/fieldComponentTypes.d.ts +8 -10
- package/dist/form/useChoiceField.d.ts +18 -0
- package/dist/form/useChoiceField.js +46 -0
- package/dist/form/useFieldValue.d.ts +7 -0
- package/dist/form/useFieldValue.js +20 -0
- package/dist/form/useParsedOpts.d.ts +3 -1
- package/dist/form/useParsedOpts.js +12 -17
- package/dist/form/utils/dependentOptions.d.ts +8 -4
- package/dist/form/utils/dependentOptions.js +25 -17
- package/dist/form/utils/fieldItems.d.ts +32 -0
- package/dist/form/utils/fieldItems.js +32 -0
- package/dist/form/utils/fieldPath.d.ts +10 -0
- package/dist/form/utils/fieldPath.js +20 -0
- package/dist/form/utils/shareEqual.d.ts +6 -0
- package/dist/form/utils/shareEqual.js +38 -0
- package/dist/graph/AnnotationBanner.js +8 -8
- package/dist/graph/Collapse.d.ts +1 -0
- package/dist/graph/Collapse.js +6 -27
- package/dist/graph/Connectors.js +5 -5
- package/dist/graph/DependencyGraph.js +20 -19
- package/dist/graph/GraphEditor.js +30 -41
- package/dist/graph/GraphEditorDialogs.js +17 -17
- package/dist/graph/GraphNode.js +1 -1
- package/dist/graph/InputDialog.js +19 -22
- package/dist/graph/InputsEditor.js +58 -66
- package/dist/graph/JobSummary.js +42 -39
- package/dist/graph/MatrixGroup.js +1 -1
- package/dist/graph/ProblemsButton.js +18 -19
- package/dist/graph/Reveal.js +1 -1
- package/dist/graph/ShortcutsButton.js +15 -18
- package/dist/graph/SuggestionInput.d.ts +5 -10
- package/dist/graph/SuggestionInput.js +14 -18
- package/dist/graph/ToolbarPopover.d.ts +11 -6
- package/dist/graph/ToolbarPopover.js +35 -67
- package/dist/graph/TreeView.js +24 -37
- package/dist/graph/WorkflowSettingsDialog.js +4 -4
- package/dist/graph/editorChrome.js +13 -12
- package/dist/graph/editorFields.js +29 -29
- package/dist/graph/editorPrimitives.d.ts +1 -1
- package/dist/graph/editorPrimitives.js +10 -7
- package/dist/graph/editorRows.js +103 -97
- package/dist/graph/fieldProblems.js +2 -2
- package/dist/graph/graphEditorState.d.ts +4 -3
- package/dist/graph/inputRefs.js +9 -9
- package/dist/graph/settingsViews.js +6 -7
- package/dist/graph/stepWith.js +6 -6
- package/dist/index.d.ts +14 -15
- package/dist/index.js +15 -14
- package/dist/list/ActionToolbar.d.ts +6 -14
- package/dist/list/ActionToolbar.js +48 -96
- package/dist/list/ListPage.d.ts +6 -12
- package/dist/list/ListPage.js +46 -29
- package/dist/list/ListPager.js +4 -4
- package/dist/list/ListTable.js +5 -5
- package/dist/list/ListViewControls.d.ts +5 -4
- package/dist/list/ListViewControls.js +177 -267
- package/dist/list/UserHoverCard.d.ts +3 -17
- package/dist/list/UserHoverCard.js +21 -45
- package/dist/list/index.d.ts +3 -4
- package/dist/list/index.js +3 -4
- package/dist/list/listSearch.js +12 -11
- package/dist/list/rowMenu.d.ts +68 -0
- package/dist/list/rowMenu.js +136 -0
- package/dist/logviewer/LogViewer.js +26 -26
- package/dist/styles.css +1 -1
- package/package.json +7 -13
- package/dist/ai/ui/Dropdown.d.ts +0 -31
- package/dist/ai/ui/Dropdown.js +0 -110
- package/dist/components/AddMenu.d.ts +0 -18
- package/dist/components/AddMenu.js +0 -46
- package/dist/components/BareModal.d.ts +0 -17
- package/dist/components/BareModal.js +0 -77
- package/dist/components/CollapsiblePanel.d.ts +0 -27
- package/dist/components/CollapsiblePanel.js +0 -77
- package/dist/components/Dropdown.d.ts +0 -28
- package/dist/components/Dropdown.js +0 -355
- package/dist/components/Listbox.d.ts +0 -21
- package/dist/components/Listbox.js +0 -119
- package/dist/components/MultiSelect.d.ts +0 -22
- package/dist/components/MultiSelect.js +0 -168
- package/dist/components/SwitchToggle.d.ts +0 -15
- package/dist/components/SwitchToggle.js +0 -57
- package/dist/components/SwitchToggleSmall.d.ts +0 -6
- package/dist/components/SwitchToggleSmall.js +0 -14
- package/dist/components/Toggle.d.ts +0 -6
- package/dist/components/Toggle.js +0 -20
- package/dist/components/dropdownUtils.d.ts +0 -37
- package/dist/components/dropdownUtils.js +0 -99
- package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -25
- package/dist/form/SpecialTypes/DropdownWrapper.js +0 -28
- package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +0 -51
- package/dist/form/SpecialTypes/FormikCustomDropdown.js +0 -119
- package/dist/form/SpecialTypes/FormikCustomInput.d.ts +0 -19
- package/dist/form/SpecialTypes/FormikCustomInput.js +0 -121
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +0 -13
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +0 -31
- package/dist/form/SpecialTypes/FormikNumericInput.d.ts +0 -9
- package/dist/form/SpecialTypes/FormikNumericInput.js +0 -60
- package/dist/form/SpecialTypes/index.d.ts +0 -3
- package/dist/list/HoverCard.d.ts +0 -24
- package/dist/list/HoverCard.js +0 -73
- package/dist/list/RowContextMenu.d.ts +0 -127
- package/dist/list/RowContextMenu.js +0 -515
|
@@ -38,13 +38,10 @@ function ComposerUsage({ children }) {
|
|
|
38
38
|
children
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
/** The two selectors every surface carries,
|
|
42
|
-
*
|
|
41
|
+
/** The two selectors every surface carries, reading as text beside whatever
|
|
42
|
+
* the surface puts next to them. */
|
|
43
43
|
function ComposerControls({ targetSession }) {
|
|
44
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ModelSelector, {
|
|
45
|
-
variant: "bare",
|
|
46
|
-
targetSession
|
|
47
|
-
}), /* @__PURE__ */ jsx(AllocationSelector, { variant: "bare" })] });
|
|
44
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ModelSelector, { targetSession }), /* @__PURE__ */ jsx(AllocationSelector, {})] });
|
|
48
45
|
}
|
|
49
46
|
/** Where the reader manages the providers behind the model picker, at the
|
|
50
47
|
* foot of a conversation list. */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { clsx } from "clsx";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
//#region src/ai/components/DragOverlay.tsx
|
|
4
4
|
function DragOverlay({ className }) {
|
|
5
5
|
return /* @__PURE__ */ jsx("div", {
|
|
6
|
-
className:
|
|
6
|
+
className: clsx("absolute inset-0 z-50 flex items-center justify-center bg-blue-500/10 border-2 border-dashed border-blue-500 backdrop-blur-sm pointer-events-none", className),
|
|
7
7
|
children: /* @__PURE__ */ jsxs("div", {
|
|
8
8
|
className: "text-center",
|
|
9
9
|
children: [/* @__PURE__ */ jsx("p", {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare function getProviderKeyFromModelId(modelId: string): string;
|
|
2
|
-
|
|
2
|
+
/** Picks the model a conversation runs on, grouped by provider. Sessions that
|
|
3
|
+
* are still connecting or not responding show as headings with their status,
|
|
4
|
+
* so the reader sees why their models are missing. */
|
|
5
|
+
export default function ModelSelector({ targetSession, }: {
|
|
6
|
+
/** A session, as "owner:name", whose models the reader is waiting for. */
|
|
3
7
|
targetSession?: string | null | undefined;
|
|
4
|
-
/** 'bare' drops the border and the icon, for a toolbar that reads as text. */
|
|
5
|
-
variant?: 'default' | 'bare';
|
|
6
8
|
}): import("react").JSX.Element;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { FaCheck } from "../../icons/fa/FaCheck.js";
|
|
2
1
|
import { FaChevronDown } from "../../icons/fa/FaChevronDown.js";
|
|
3
2
|
import { FaCloud } from "../../icons/fa/FaCloud.js";
|
|
4
|
-
import { FaCog } from "../../icons/fa/FaCog.js";
|
|
5
3
|
import { FaExclamationTriangle } from "../../icons/fa/FaExclamationTriangle.js";
|
|
6
|
-
import { FaRobot } from "../../icons/fa/FaRobot.js";
|
|
7
4
|
import { FaUndoAlt } from "../../icons/fa/FaUndoAlt.js";
|
|
5
|
+
import { Combobox } from "../../components/Combobox.js";
|
|
8
6
|
import { useChatConfig } from "../core/config.js";
|
|
9
|
-
import { providerIssueFor } from "../core/providerIssues.js";
|
|
7
|
+
import { issueDetail, issueLabel, providerIssueFor } from "../core/providerIssues.js";
|
|
10
8
|
import { useChat } from "../core/ChatProvider.js";
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import { Fragment
|
|
14
|
-
import {
|
|
9
|
+
import { chipClassName } from "../ui/chip.js";
|
|
10
|
+
import { clsx } from "clsx";
|
|
11
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { useMemo } from "react";
|
|
15
13
|
//#region src/ai/components/ModelSelector.tsx
|
|
16
14
|
var ORG_OWNER = "org";
|
|
17
15
|
/** Who registered a provider: the provider list's owner when the adapter
|
|
@@ -21,14 +19,11 @@ function providerOwner(info, model) {
|
|
|
21
19
|
if (info) return info.user === ORG_OWNER ? "" : info.user;
|
|
22
20
|
return model?.provider_owner ?? "";
|
|
23
21
|
}
|
|
24
|
-
/** The search field plus the list's max-h-80, so the flip decision matches
|
|
25
|
-
* what renders. */
|
|
26
|
-
var MAX_PANEL_HEIGHT_PX = 380;
|
|
27
22
|
function CspIcon({ cspKind, className }) {
|
|
28
23
|
const { slots } = useChatConfig();
|
|
29
24
|
const custom = slots.providerIcon?.(cspKind, className);
|
|
30
|
-
if (custom) return /* @__PURE__ */ jsx(Fragment
|
|
31
|
-
return /* @__PURE__ */ jsx(FaCloud, { className:
|
|
25
|
+
if (custom) return /* @__PURE__ */ jsx(Fragment, { children: custom });
|
|
26
|
+
return /* @__PURE__ */ jsx(FaCloud, { className: clsx("text-purple-500", className) });
|
|
32
27
|
}
|
|
33
28
|
function getProviderKeyFromModelId(modelId) {
|
|
34
29
|
const idx = modelId.indexOf("/");
|
|
@@ -54,339 +49,107 @@ function groupModelsByProvider(models) {
|
|
|
54
49
|
}
|
|
55
50
|
return groups;
|
|
56
51
|
}
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
/** Picks the model a conversation runs on, grouped by provider. Sessions that
|
|
53
|
+
* are still connecting or not responding show as headings with their status,
|
|
54
|
+
* so the reader sees why their models are missing. */
|
|
55
|
+
function ModelSelector({ targetSession }) {
|
|
59
56
|
const { providers, models, unreachableSessions, providerIssues, selectedProvider, setSelectedProvider, isLoadingModels, hasLoadedModels, modelsError, refreshModels, currentUser } = useChat();
|
|
60
|
-
const {
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const containerRef = useRef(null);
|
|
71
|
-
const dropdownRef = useRef(null);
|
|
72
|
-
const buttonRef = useRef(null);
|
|
73
|
-
const inputRef = useRef(null);
|
|
74
|
-
const [mounted, setMounted] = useState(false);
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
setMounted(true);
|
|
77
|
-
}, []);
|
|
78
|
-
const updateDropdownPosition = useCallback(() => {
|
|
79
|
-
if (!buttonRef.current) return;
|
|
80
|
-
const rect = buttonRef.current.getBoundingClientRect();
|
|
81
|
-
const below = window.innerHeight - rect.bottom;
|
|
82
|
-
setDropdownPosition({
|
|
83
|
-
top: rect.bottom + 4,
|
|
84
|
-
bottom: window.innerHeight - rect.top + 4,
|
|
85
|
-
left: rect.left,
|
|
86
|
-
width: Math.max(rect.width, 320),
|
|
87
|
-
flipped: below < MAX_PANEL_HEIGHT_PX && rect.top > below
|
|
57
|
+
const { strings } = useChatConfig();
|
|
58
|
+
const t = strings.modelPicker;
|
|
59
|
+
const targetSessionFound = !!targetSession && models.some((m) => m.id.startsWith(`session:${targetSession}/`));
|
|
60
|
+
const targetSessionStatus = !targetSession ? null : isLoadingModels ? "connecting" : hasLoadedModels && !targetSessionFound ? "offline" : null;
|
|
61
|
+
const groups = useMemo(() => {
|
|
62
|
+
const status = (label, description) => ({
|
|
63
|
+
label,
|
|
64
|
+
icon: /* @__PURE__ */ jsx(FaCloud, { className: "h-3 w-3 text-amber-500" }),
|
|
65
|
+
description,
|
|
66
|
+
items: []
|
|
88
67
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
updateDropdownPosition();
|
|
109
|
-
window.addEventListener("scroll", updateDropdownPosition, true);
|
|
110
|
-
window.addEventListener("resize", updateDropdownPosition);
|
|
111
|
-
return () => {
|
|
112
|
-
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
113
|
-
window.removeEventListener("resize", updateDropdownPosition);
|
|
114
|
-
};
|
|
115
|
-
}, [isOpen, updateDropdownPosition]);
|
|
116
|
-
useEffect(() => {
|
|
117
|
-
if (isOpen && inputRef.current) inputRef.current.focus();
|
|
118
|
-
}, [isOpen]);
|
|
119
|
-
const filteredModels = useMemo(() => {
|
|
120
|
-
if (!searchQuery.trim()) return models;
|
|
121
|
-
const query = searchQuery.toLowerCase();
|
|
122
|
-
return models.filter((model) => getModelNameFromId(model.id).toLowerCase().includes(query) || (model.provider || "").toLowerCase().includes(query) || (model.name || "").toLowerCase().includes(query));
|
|
123
|
-
}, [models, searchQuery]);
|
|
124
|
-
const groupedModels = useMemo(() => groupModelsByProvider(filteredModels), [filteredModels]);
|
|
125
|
-
const selectedModelInfo = models.find((m) => m.id === selectedProvider);
|
|
126
|
-
const selectedModelName = selectedModelInfo ? getModelLabel(selectedModelInfo) : null;
|
|
127
|
-
const selectedProviderName = selectedModelInfo?.provider || null;
|
|
128
|
-
const issueLabel = (issue) => issue.status === "unauthorized" ? strings.providerIssue.keyRejected : strings.providerIssue.unreachable;
|
|
129
|
-
const issueDetail = (issue) => issue.message || (issue.status === "unauthorized" ? strings.providerIssue.keyRejectedHint : strings.providerIssue.unreachableHint);
|
|
130
|
-
const issueSummary = (issue) => `${issueLabel(issue)} \u2014 ${issueDetail(issue)}`;
|
|
131
|
-
const selectedModelIssue = providerIssueFor(providerIssues, selectedModelInfo);
|
|
132
|
-
const handleSelect = (modelId) => {
|
|
133
|
-
setSelectedProvider(modelId);
|
|
134
|
-
setIsOpen(false);
|
|
135
|
-
setSearchQuery("");
|
|
136
|
-
};
|
|
137
|
-
const targetSessionDisplayName = targetSession?.split(":").pop();
|
|
138
|
-
const targetSessionFound = targetSession && models.length > 0 ? models.some((m) => m.id.startsWith(`session:${targetSession}/`)) : false;
|
|
139
|
-
const targetSessionStatus = targetSession ? isLoadingModels ? "connecting" : hasLoadedModels && !targetSessionFound ? "offline" : null : null;
|
|
140
|
-
const boxClass = bare ? "flex items-center gap-1.5 rounded-full h-8 px-2.5 min-w-0 max-w-[280px]" : "flex items-center gap-2 px-3 h-8 rounded-lg min-w-[180px] max-w-[280px]";
|
|
141
|
-
const textClass = bare ? "text-[13px]" : "text-sm";
|
|
142
|
-
if (isLoadingModels && models.length === 0 && !targetSession) return /* @__PURE__ */ jsx("div", {
|
|
143
|
-
ref: containerRef,
|
|
144
|
-
className: "relative min-w-0",
|
|
145
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
146
|
-
className: boxClass,
|
|
147
|
-
children: [!bare && /* @__PURE__ */ jsx(FaRobot, { className: "h-4 w-4 text-purple-500 flex-shrink-0 animate-pulse" }), /* @__PURE__ */ jsx("span", {
|
|
148
|
-
className: cx(textClass, "theme-muted-text"),
|
|
149
|
-
children: "Loading models..."
|
|
150
|
-
})]
|
|
151
|
-
})
|
|
152
|
-
});
|
|
153
|
-
if (modelsError && models.length === 0) return /* @__PURE__ */ jsx("div", {
|
|
154
|
-
ref: containerRef,
|
|
155
|
-
className: "relative min-w-0",
|
|
156
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
157
|
-
className: boxClass,
|
|
158
|
-
children: [
|
|
159
|
-
!bare && /* @__PURE__ */ jsx(FaRobot, { className: "h-4 w-4 text-red-500 flex-shrink-0" }),
|
|
160
|
-
/* @__PURE__ */ jsx("span", {
|
|
161
|
-
className: cx(textClass, "text-red-600"),
|
|
162
|
-
children: "Failed to load models"
|
|
68
|
+
const sessions = unreachableSessions.filter((s) => `${s.owner}:${s.name}` !== targetSession).map((s) => status(s.name, t.notResponding));
|
|
69
|
+
if (targetSession && targetSessionStatus) sessions.unshift(status(targetSession.split(":").pop() ?? targetSession, targetSessionStatus === "connecting" ? t.connecting : t.notResponding));
|
|
70
|
+
const byProvider = [...groupModelsByProvider(models)].map(([providerKey, providerModels]) => {
|
|
71
|
+
const info = providers.find((p) => `${p.user}:${p.name}` === providerKey);
|
|
72
|
+
const first = providerModels[0];
|
|
73
|
+
const name = first?.provider || info?.name || providerKey;
|
|
74
|
+
const platform = info?.platformLabel;
|
|
75
|
+
const owner = providerOwner(info, first);
|
|
76
|
+
const issue = providerIssueFor(providerIssues, first);
|
|
77
|
+
const description = [
|
|
78
|
+
platform && platform.toLowerCase() !== name.toLowerCase() ? platform : null,
|
|
79
|
+
owner && owner !== currentUser.username ? t.sharedBy(owner) : null,
|
|
80
|
+
issue ? issueLabel(strings.providerIssue, issue) : null
|
|
81
|
+
].filter(Boolean).join(" · ");
|
|
82
|
+
return {
|
|
83
|
+
label: name,
|
|
84
|
+
icon: /* @__PURE__ */ jsx(CspIcon, {
|
|
85
|
+
cspKind: info?.cspKind ?? "other",
|
|
86
|
+
className: "h-3 w-3"
|
|
163
87
|
}),
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
})
|
|
88
|
+
description: description || void 0,
|
|
89
|
+
items: providerModels.map((model) => ({
|
|
90
|
+
label: getModelLabel(model),
|
|
91
|
+
value: model.id,
|
|
92
|
+
disabled: !!issue
|
|
93
|
+
}))
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
return [...sessions, ...byProvider];
|
|
97
|
+
}, [
|
|
98
|
+
models,
|
|
99
|
+
providers,
|
|
100
|
+
providerIssues,
|
|
101
|
+
unreachableSessions,
|
|
102
|
+
targetSession,
|
|
103
|
+
targetSessionStatus,
|
|
104
|
+
currentUser.username,
|
|
105
|
+
strings.providerIssue,
|
|
106
|
+
t
|
|
107
|
+
]);
|
|
108
|
+
if (isLoadingModels && models.length === 0 && !targetSession) return /* @__PURE__ */ jsx("span", {
|
|
109
|
+
className: clsx(chipClassName, "cursor-default animate-pulse"),
|
|
110
|
+
children: t.loading
|
|
172
111
|
});
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
112
|
+
if (modelsError && models.length === 0) return /* @__PURE__ */ jsxs("span", {
|
|
113
|
+
className: clsx(chipClassName, "cursor-default text-(--theme-error)"),
|
|
114
|
+
children: [t.failed, /* @__PURE__ */ jsxs("button", {
|
|
115
|
+
type: "button",
|
|
116
|
+
onClick: () => refreshModels(),
|
|
117
|
+
className: "flex items-center gap-1 text-xs text-(--theme-element) hover:underline",
|
|
118
|
+
children: [/* @__PURE__ */ jsx(FaUndoAlt, { className: "h-2.5 w-2.5" }), t.retry]
|
|
119
|
+
})]
|
|
120
|
+
});
|
|
121
|
+
if (groups.length === 0 && hasLoadedModels) return /* @__PURE__ */ jsx("span", {
|
|
122
|
+
className: clsx(chipClassName, "cursor-default"),
|
|
123
|
+
children: t.none
|
|
183
124
|
});
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
125
|
+
const selected = models.find((m) => m.id === selectedProvider);
|
|
126
|
+
const issue = providerIssueFor(providerIssues, selected);
|
|
127
|
+
return /* @__PURE__ */ jsx(Combobox, {
|
|
128
|
+
"aria-label": t.choose,
|
|
129
|
+
placeholder: t.search,
|
|
130
|
+
items: groups,
|
|
131
|
+
value: selectedProvider,
|
|
132
|
+
onValueChange: (id) => id && setSelectedProvider(id),
|
|
133
|
+
disabled: groups.length === 0,
|
|
134
|
+
triggerTooltip: issue ? `${issueLabel(strings.providerIssue, issue)} \u2014 ${issueDetail(strings.providerIssue, issue)}` : void 0,
|
|
135
|
+
trigger: /* @__PURE__ */ jsxs("button", {
|
|
190
136
|
type: "button",
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
children: selectedModelName ? /* @__PURE__ */ jsxs("div", {
|
|
201
|
-
className: "flex items-baseline gap-1.5 min-w-0",
|
|
202
|
-
children: [
|
|
203
|
-
/* @__PURE__ */ jsx("span", {
|
|
204
|
-
title: selectedModelName,
|
|
205
|
-
className: cx("truncate", bare ? "text-[13px] font-medium theme-text" : "text-sm font-medium text-(--theme-panel)"),
|
|
206
|
-
children: selectedModelName
|
|
207
|
-
}),
|
|
208
|
-
selectedProviderName && /* @__PURE__ */ jsx("span", {
|
|
209
|
-
title: selectedProviderName,
|
|
210
|
-
className: "theme-muted-text truncate flex-shrink-0 max-w-[45%] text-xs",
|
|
211
|
-
children: selectedProviderName
|
|
212
|
-
}),
|
|
213
|
-
selectedModelIssue && /* @__PURE__ */ jsx(FaExclamationTriangle, {
|
|
214
|
-
title: issueSummary(selectedModelIssue),
|
|
215
|
-
className: "h-3.5 w-3.5 text-amber-500 flex-shrink-0 self-center"
|
|
216
|
-
})
|
|
217
|
-
]
|
|
218
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
219
|
-
className: cx(textClass, targetSessionStatus === "connecting" ? "text-amber-600" : "theme-muted-text"),
|
|
220
|
-
children: triggerText
|
|
221
|
-
})
|
|
137
|
+
className: chipClassName,
|
|
138
|
+
children: [selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx("span", {
|
|
140
|
+
className: "truncate font-medium theme-text",
|
|
141
|
+
children: getModelLabel(selected)
|
|
142
|
+
}),
|
|
143
|
+
selected.provider && /* @__PURE__ */ jsx("span", {
|
|
144
|
+
className: "max-w-[45%] shrink-0 truncate text-xs",
|
|
145
|
+
children: selected.provider
|
|
222
146
|
}),
|
|
223
|
-
/* @__PURE__ */ jsx(
|
|
224
|
-
]
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
onKeyDown: (e) => {
|
|
230
|
-
if (e.key === "Escape") {
|
|
231
|
-
e.preventDefault();
|
|
232
|
-
setIsOpen(false);
|
|
233
|
-
buttonRef.current?.focus();
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
style: {
|
|
237
|
-
position: "fixed",
|
|
238
|
-
...dropdownPosition.flipped ? { bottom: dropdownPosition.bottom } : { top: dropdownPosition.top },
|
|
239
|
-
left: dropdownPosition.left,
|
|
240
|
-
width: dropdownPosition.width,
|
|
241
|
-
zIndex: 9999
|
|
242
|
-
},
|
|
243
|
-
className: cx("theme-panel rounded-lg shadow-lg", "border theme-border", "overflow-hidden"),
|
|
244
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
245
|
-
className: "p-2 border-b theme-border",
|
|
246
|
-
children: /* @__PURE__ */ jsx("input", {
|
|
247
|
-
ref: inputRef,
|
|
248
|
-
type: "text",
|
|
249
|
-
value: searchQuery,
|
|
250
|
-
onChange: (e) => setSearchQuery(e.target.value),
|
|
251
|
-
placeholder: "Search models...",
|
|
252
|
-
className: cx("w-full px-3 py-2 text-sm rounded-md", "theme-muted-panel", "border theme-border", "focus:outline-none focus:ring-2 focus:ring-blue-500", "placeholder:theme-muted-text")
|
|
253
|
-
})
|
|
254
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
255
|
-
className: "max-h-80 overflow-y-auto",
|
|
256
|
-
children: [
|
|
257
|
-
targetSessionStatus && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
258
|
-
className: "px-3 py-1.5 bg-amber-500/5 sticky top-0",
|
|
259
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
260
|
-
className: "flex items-center gap-2",
|
|
261
|
-
children: [
|
|
262
|
-
/* @__PURE__ */ jsx(FaCloud, { className: "h-3 w-3 text-amber-500" }),
|
|
263
|
-
/* @__PURE__ */ jsx("span", {
|
|
264
|
-
className: "text-xs font-semibold text-amber-600 uppercase tracking-wide flex-1",
|
|
265
|
-
children: targetSessionDisplayName
|
|
266
|
-
}),
|
|
267
|
-
/* @__PURE__ */ jsx("span", {
|
|
268
|
-
className: cx("text-[10px] px-1.5 py-0.5 rounded-full", targetSessionStatus === "connecting" ? "text-amber-600 bg-amber-500/10 animate-pulse" : "text-amber-500 bg-amber-500/10"),
|
|
269
|
-
children: targetSessionStatus === "connecting" ? "Connecting..." : "Not responding"
|
|
270
|
-
})
|
|
271
|
-
]
|
|
272
|
-
})
|
|
273
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
274
|
-
className: "px-4 py-2 flex items-center gap-2",
|
|
275
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
276
|
-
className: "text-sm theme-muted-text italic",
|
|
277
|
-
children: targetSessionStatus === "connecting" ? "Loading session models..." : "Service not responding — ensure it is running on the remote host"
|
|
278
|
-
})
|
|
279
|
-
})] }),
|
|
280
|
-
unreachableSessions.filter((s) => !targetSession || `${s.owner}:${s.name}` !== targetSession).map((s) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
281
|
-
className: "px-3 py-1.5 bg-amber-500/5 sticky top-0",
|
|
282
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
283
|
-
className: "flex items-center gap-2",
|
|
284
|
-
children: [
|
|
285
|
-
/* @__PURE__ */ jsx(FaCloud, { className: "h-3 w-3 text-amber-500" }),
|
|
286
|
-
/* @__PURE__ */ jsx("span", {
|
|
287
|
-
className: "text-xs font-semibold text-amber-600 uppercase tracking-wide flex-1",
|
|
288
|
-
children: s.name
|
|
289
|
-
}),
|
|
290
|
-
/* @__PURE__ */ jsx("span", {
|
|
291
|
-
className: "text-[10px] text-amber-500 bg-amber-500/10 px-1.5 py-0.5 rounded-full",
|
|
292
|
-
children: "Not responding"
|
|
293
|
-
})
|
|
294
|
-
]
|
|
295
|
-
})
|
|
296
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
297
|
-
className: "px-4 py-2 flex items-center gap-2",
|
|
298
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
299
|
-
className: "text-sm theme-muted-text italic",
|
|
300
|
-
children: "Service not responding — ensure it is running on the remote host"
|
|
301
|
-
})
|
|
302
|
-
})] }, `${s.owner}:${s.name}`)),
|
|
303
|
-
groupedModels.size === 0 && !targetSessionStatus && unreachableSessions.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
304
|
-
className: "p-4 text-center theme-muted-text text-sm",
|
|
305
|
-
children: "No models found"
|
|
306
|
-
}) : Array.from(groupedModels.entries()).map(([providerKey, providerModels]) => {
|
|
307
|
-
const providerInfo = providers.find((p) => `${p.user}:${p.name}` === providerKey);
|
|
308
|
-
const providerName = providerModels[0]?.provider || providerInfo?.name || "Unknown Provider";
|
|
309
|
-
const platform = providerInfo?.platformLabel;
|
|
310
|
-
const platformSuffix = providerInfo && platform && platform.toLowerCase() !== providerName.toLowerCase() ? platform : null;
|
|
311
|
-
const isOwner = providerInfo?.user === currentUser.username;
|
|
312
|
-
const owner = providerOwner(providerInfo, providerModels[0]);
|
|
313
|
-
const headerSuffix = [platformSuffix, owner && owner !== currentUser.username ? strings.modelPicker.sharedBy(owner) : null].filter(Boolean).join(" · ");
|
|
314
|
-
const settingsHref = providerInfo && extraLinks.providerSettings ? extraLinks.providerSettings(providerInfo.user, providerInfo.name) : null;
|
|
315
|
-
const issue = providerIssueFor(providerIssues, providerModels[0]);
|
|
316
|
-
return /* @__PURE__ */ jsxs("div", { children: [
|
|
317
|
-
/* @__PURE__ */ jsx("div", {
|
|
318
|
-
className: "px-3 py-1.5 theme-muted-panel sticky top-0",
|
|
319
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
320
|
-
className: "flex items-center gap-2",
|
|
321
|
-
children: [
|
|
322
|
-
/* @__PURE__ */ jsx(CspIcon, {
|
|
323
|
-
cspKind: providerInfo?.cspKind ?? "other",
|
|
324
|
-
className: "h-3 w-3"
|
|
325
|
-
}),
|
|
326
|
-
/* @__PURE__ */ jsx("span", {
|
|
327
|
-
className: "text-xs font-semibold theme-muted-text uppercase tracking-wide",
|
|
328
|
-
children: providerName
|
|
329
|
-
}),
|
|
330
|
-
/* @__PURE__ */ jsx("span", {
|
|
331
|
-
className: "min-w-0 flex-1 truncate text-xs theme-muted-text",
|
|
332
|
-
children: headerSuffix ? `· ${headerSuffix}` : ""
|
|
333
|
-
}),
|
|
334
|
-
/* @__PURE__ */ jsxs("span", {
|
|
335
|
-
className: "text-xs theme-muted-text",
|
|
336
|
-
children: [
|
|
337
|
-
"(",
|
|
338
|
-
providerModels.length,
|
|
339
|
-
")"
|
|
340
|
-
]
|
|
341
|
-
}),
|
|
342
|
-
issue && /* @__PURE__ */ jsx("span", {
|
|
343
|
-
className: "text-[10px] text-amber-600 bg-amber-500/10 px-1.5 py-0.5 rounded-full flex-shrink-0",
|
|
344
|
-
children: issueLabel(issue)
|
|
345
|
-
}),
|
|
346
|
-
isOwner && settingsHref && /* @__PURE__ */ jsx(LinkComponent, {
|
|
347
|
-
target: {
|
|
348
|
-
kind: "external",
|
|
349
|
-
href: settingsHref
|
|
350
|
-
},
|
|
351
|
-
onClick: (e) => e.stopPropagation(),
|
|
352
|
-
className: "p-0.5 rounded hover:theme-hover theme-muted-text hover:text-blue-600 transition-colors",
|
|
353
|
-
title: "Manage provider",
|
|
354
|
-
children: /* @__PURE__ */ jsx(FaCog, { className: "h-3 w-3" })
|
|
355
|
-
})
|
|
356
|
-
]
|
|
357
|
-
})
|
|
358
|
-
}),
|
|
359
|
-
issue && /* @__PURE__ */ jsxs("div", {
|
|
360
|
-
className: "flex items-start gap-2 px-4 py-1.5 bg-amber-500/5",
|
|
361
|
-
children: [/* @__PURE__ */ jsx(FaExclamationTriangle, { className: "h-3 w-3 text-amber-500 flex-shrink-0 mt-0.5" }), /* @__PURE__ */ jsx("span", {
|
|
362
|
-
className: "text-xs text-amber-600 line-clamp-2",
|
|
363
|
-
children: issueDetail(issue)
|
|
364
|
-
})]
|
|
365
|
-
}),
|
|
366
|
-
providerModels.map((model) => {
|
|
367
|
-
const modelName = getModelLabel(model);
|
|
368
|
-
const isSelected = model.id === selectedProvider;
|
|
369
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
370
|
-
type: "button",
|
|
371
|
-
"aria-disabled": !!issue,
|
|
372
|
-
title: issue ? issueSummary(issue) : void 0,
|
|
373
|
-
onClick: () => {
|
|
374
|
-
if (!issue) handleSelect(model.id);
|
|
375
|
-
},
|
|
376
|
-
className: cx("w-full flex items-center gap-3 px-4 py-2 text-left", issue ? "opacity-40 cursor-not-allowed" : "cursor-pointer hover:bg-blue-500/5 transition-colors", isSelected && "bg-blue-500/10"),
|
|
377
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
378
|
-
title: modelName,
|
|
379
|
-
className: cx("flex-1 min-w-0 text-sm truncate", isSelected ? "text-blue-600 font-medium" : ""),
|
|
380
|
-
style: !isSelected ? { color: "var(--theme-panel, #1f2937)" } : void 0,
|
|
381
|
-
children: modelName
|
|
382
|
-
}), isSelected && /* @__PURE__ */ jsx(FaCheck, { className: "h-3.5 w-3.5 text-blue-600 flex-shrink-0" })]
|
|
383
|
-
}, model.id);
|
|
384
|
-
})
|
|
385
|
-
] }, providerKey);
|
|
386
|
-
})
|
|
387
|
-
]
|
|
388
|
-
})]
|
|
389
|
-
}), document.body)]
|
|
147
|
+
issue && /* @__PURE__ */ jsx(FaExclamationTriangle, { className: "h-3.5 w-3.5 shrink-0 text-amber-500" })
|
|
148
|
+
] }) : /* @__PURE__ */ jsx("span", {
|
|
149
|
+
className: clsx("truncate", targetSessionStatus === "connecting" && "animate-pulse"),
|
|
150
|
+
children: targetSessionStatus === "connecting" ? t.connecting : t.select
|
|
151
|
+
}), /* @__PURE__ */ jsx(FaChevronDown, { className: "h-3 w-3 shrink-0" })]
|
|
152
|
+
})
|
|
390
153
|
});
|
|
391
154
|
}
|
|
392
155
|
//#endregion
|
|
@@ -6,9 +6,9 @@ import { formatFileSize } from "../utils.js";
|
|
|
6
6
|
import Markdown from "../ui/Markdown.js";
|
|
7
7
|
import { fencePaste } from "../core/pasteLanguage.js";
|
|
8
8
|
import { splitPastes } from "../core/pastes.js";
|
|
9
|
-
import
|
|
10
|
-
import { Fragment } from "react";
|
|
11
|
-
import { Fragment as Fragment$1
|
|
9
|
+
import { clsx } from "clsx";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { Fragment as Fragment$1 } from "react";
|
|
12
12
|
//#region src/ai/components/PastedText.tsx
|
|
13
13
|
/** A paste sent, or about to be sent, as its saved file. */
|
|
14
14
|
function PasteFileCard({ id, lines, bytes, saving = false, error, onRemove }) {
|
|
@@ -16,7 +16,7 @@ function PasteFileCard({ id, lines, bytes, saving = false, error, onRemove }) {
|
|
|
16
16
|
const detail = error ?? (saving ? t.saving : `${t.lines(lines)} · ${formatFileSize(bytes)}`);
|
|
17
17
|
return /* @__PURE__ */ jsxs("div", {
|
|
18
18
|
"data-testid": "paste-file-card",
|
|
19
|
-
className:
|
|
19
|
+
className: clsx("inline-flex max-w-full items-center gap-2.5 rounded-xl px-3 py-2 align-top whitespace-normal", "bg-(--theme-panel-bg)", error ? "border border-red-500" : "chat-hairline"),
|
|
20
20
|
children: [
|
|
21
21
|
/* @__PURE__ */ jsx(FiFile, { className: "h-5 w-5 flex-shrink-0 theme-muted-text" }),
|
|
22
22
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -25,7 +25,7 @@ function PasteFileCard({ id, lines, bytes, saving = false, error, onRemove }) {
|
|
|
25
25
|
className: "truncate text-sm font-medium theme-text",
|
|
26
26
|
children: id ? `paste-${id}.txt` : t.title
|
|
27
27
|
}), /* @__PURE__ */ jsx("div", {
|
|
28
|
-
className:
|
|
28
|
+
className: clsx("truncate text-xs", error ? "text-red-500" : "theme-muted-text"),
|
|
29
29
|
children: detail
|
|
30
30
|
})]
|
|
31
31
|
}),
|
|
@@ -45,23 +45,23 @@ function PasteFileCard({ id, lines, bytes, saving = false, error, onRemove }) {
|
|
|
45
45
|
* it reads as, one sent as its file as a card. The blank lines the composer puts around a
|
|
46
46
|
* paste would stack on the block's own spacing, so they are dropped. */
|
|
47
47
|
function UserMessageText({ content, pastes }) {
|
|
48
|
-
if (!pastes?.length) return /* @__PURE__ */ jsx(Fragment
|
|
48
|
+
if (!pastes?.length) return /* @__PURE__ */ jsx(Fragment, { children: content });
|
|
49
49
|
const segments = splitPastes(content, pastes);
|
|
50
50
|
const shows = (seg) => typeof seg !== "string" || seg.trim() !== "";
|
|
51
|
-
const blockSpacing = (i) =>
|
|
52
|
-
return /* @__PURE__ */ jsx(Fragment
|
|
51
|
+
const blockSpacing = (i) => clsx(segments.slice(0, i).some(shows) ? "mt-2.5" : "mt-0", segments.slice(i + 1).some(shows) ? "mb-2.5" : "mb-0");
|
|
52
|
+
return /* @__PURE__ */ jsx(Fragment, { children: segments.map((segment, i) => {
|
|
53
53
|
if (typeof segment === "string") {
|
|
54
54
|
let text = segment;
|
|
55
55
|
if (i > 0) text = text.replace(/^\n+/, "");
|
|
56
56
|
if (i < segments.length - 1) text = text.replace(/\n+$/, "");
|
|
57
|
-
return text ? /* @__PURE__ */ jsx(Fragment, { children: text }, i) : null;
|
|
57
|
+
return text ? /* @__PURE__ */ jsx(Fragment$1, { children: text }, i) : null;
|
|
58
58
|
}
|
|
59
59
|
if (segment.inline && segment.text !== void 0) return /* @__PURE__ */ jsx("span", {
|
|
60
|
-
className:
|
|
60
|
+
className: clsx("chat-paste-code block", blockSpacing(i)),
|
|
61
61
|
children: /* @__PURE__ */ jsx(Markdown, { children: fencePaste(segment.text) })
|
|
62
62
|
}, i);
|
|
63
63
|
return /* @__PURE__ */ jsx("span", {
|
|
64
|
-
className:
|
|
64
|
+
className: clsx("flex [&>*]:flex-1", blockSpacing(i)),
|
|
65
65
|
children: /* @__PURE__ */ jsx(PasteFileCard, {
|
|
66
66
|
id: segment.id,
|
|
67
67
|
lines: segment.lines,
|