@parallelworks/ui 0.40.1 → 0.42.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/adapter/memoryStore.js +7 -0
- package/dist/ai/adapter/mock/mockAdapter.js +52 -17
- package/dist/ai/adapter/openai/createOpenAIStream.js +1 -1
- package/dist/ai/adapter/openai/index.d.ts +1 -1
- package/dist/ai/adapter/openai/sse.d.ts +8 -2
- package/dist/ai/adapter/openai/sse.js +40 -4
- package/dist/ai/adapter/openai/wire.d.ts +6 -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 +4 -4
- package/dist/ai/core/config.js +1 -1
- package/dist/ai/core/parts.d.ts +5 -0
- package/dist/ai/core/parts.js +28 -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 +66 -0
- package/dist/components/Combobox.js +393 -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 +17 -36
- package/dist/components/CreateModal.js +97 -259
- 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/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/types/fieldComponentTypes.d.ts +8 -10
- package/dist/form/useChoiceField.d.ts +20 -0
- package/dist/form/useChoiceField.js +49 -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 +10 -0
- package/dist/form/utils/fieldItems.js +11 -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 +63 -0
- package/dist/list/rowMenu.js +134 -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
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { BiSolidTrashAlt } from "../../icons/bi/BiSolidTrashAlt.js";
|
|
2
2
|
import { PiShareBold } from "../../icons/pi/PiShareBold.js";
|
|
3
|
+
import { Tooltip } from "../../components/Tooltip.js";
|
|
4
|
+
import { Combobox } from "../../components/Combobox.js";
|
|
3
5
|
import { ConfirmModal } from "../../components/ConfirmModal.js";
|
|
4
6
|
import Loader from "../../components/Loader.js";
|
|
7
|
+
import { Select } from "../../components/Select.js";
|
|
5
8
|
import { useChatConfig } from "../core/config.js";
|
|
6
9
|
import { useChat } from "../core/ChatProvider.js";
|
|
7
|
-
import
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
11
|
import { useCallback, useEffect, useState, useTransition } from "react";
|
|
9
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
12
|
//#region src/ai/components/ShareDialog.tsx
|
|
11
13
|
function isTeamPermission(p) {
|
|
12
14
|
return !!p.team && !p.entireOrganization;
|
|
@@ -122,6 +124,13 @@ function ShareDialog({ conversationId, isOpen, onClose }) {
|
|
|
122
124
|
}, []);
|
|
123
125
|
if (!sharing) return null;
|
|
124
126
|
const teamPermissions = permissions.filter(isTeamPermission);
|
|
127
|
+
const permissionItems = [{
|
|
128
|
+
label: t.viewOnly,
|
|
129
|
+
value: "view"
|
|
130
|
+
}, {
|
|
131
|
+
label: t.canCollaborate,
|
|
132
|
+
value: "collaborate"
|
|
133
|
+
}];
|
|
125
134
|
const availableTeams = teams.filter((team) => !permissions.some((p) => p.team === team.id));
|
|
126
135
|
return /* @__PURE__ */ jsx(ConfirmModal, {
|
|
127
136
|
open: isOpen,
|
|
@@ -140,7 +149,7 @@ function ShareDialog({ conversationId, isOpen, onClose }) {
|
|
|
140
149
|
size: 24,
|
|
141
150
|
text: strings.modal.loading
|
|
142
151
|
})
|
|
143
|
-
}) : /* @__PURE__ */ jsxs(Fragment
|
|
152
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
144
153
|
/* @__PURE__ */ jsxs("div", {
|
|
145
154
|
className: "border theme-border rounded-lg p-3",
|
|
146
155
|
children: [/* @__PURE__ */ jsx("h3", {
|
|
@@ -193,24 +202,25 @@ function ShareDialog({ conversationId, isOpen, onClose }) {
|
|
|
193
202
|
children: perm.teamName || perm.team
|
|
194
203
|
}), /* @__PURE__ */ jsxs("div", {
|
|
195
204
|
className: "flex items-center gap-2",
|
|
196
|
-
children: [/* @__PURE__ */ jsx(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
205
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
206
|
+
className: "w-40",
|
|
207
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
208
|
+
items: permissionItems,
|
|
209
|
+
value: perm.permission,
|
|
210
|
+
onValueChange: (level) => {
|
|
211
|
+
if (level !== null) handleTeamPermissionChange(perm.team, level);
|
|
212
|
+
},
|
|
213
|
+
"aria-label": perm.teamName || perm.team
|
|
214
|
+
})
|
|
215
|
+
}), /* @__PURE__ */ jsx(Tooltip, {
|
|
216
|
+
content: t.remove,
|
|
217
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
218
|
+
type: "button",
|
|
219
|
+
onClick: () => handleRemoveTeam(perm.team),
|
|
220
|
+
className: "p-1 rounded hover:bg-red-500/10",
|
|
221
|
+
"aria-label": `${t.remove} ${perm.teamName || perm.team}`,
|
|
222
|
+
children: /* @__PURE__ */ jsx(BiSolidTrashAlt, { className: "w-3 h-3 text-red-500" })
|
|
223
|
+
})
|
|
214
224
|
})]
|
|
215
225
|
})]
|
|
216
226
|
}, perm.team))
|
|
@@ -218,19 +228,17 @@ function ShareDialog({ conversationId, isOpen, onClose }) {
|
|
|
218
228
|
className: "text-sm theme-muted-text mb-3",
|
|
219
229
|
children: t.noGroups
|
|
220
230
|
}),
|
|
221
|
-
availableTeams.length > 0 && /* @__PURE__ */ jsx(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
textBoxClassName: "text-sm border theme-border rounded px-2 py-1.5 w-full"
|
|
233
|
-
})
|
|
231
|
+
availableTeams.length > 0 && /* @__PURE__ */ jsx(Combobox, {
|
|
232
|
+
items: availableTeams.map((team) => ({
|
|
233
|
+
label: team.name,
|
|
234
|
+
value: team.id
|
|
235
|
+
})),
|
|
236
|
+
value: null,
|
|
237
|
+
onValueChange: (teamId) => {
|
|
238
|
+
if (teamId !== null) handleAddTeam(teamId);
|
|
239
|
+
},
|
|
240
|
+
placeholder: t.addGroups,
|
|
241
|
+
"aria-label": t.addGroups
|
|
234
242
|
})
|
|
235
243
|
]
|
|
236
244
|
}),
|
|
@@ -247,7 +255,7 @@ function ShareButton({ conversationId, disabled = false }) {
|
|
|
247
255
|
const { adapter } = useChat();
|
|
248
256
|
const [isOpen, setIsOpen] = useState(false);
|
|
249
257
|
if (!adapter.sharing) return null;
|
|
250
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
258
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("button", {
|
|
251
259
|
type: "button",
|
|
252
260
|
onClick: () => setIsOpen(true),
|
|
253
261
|
disabled,
|
|
@@ -11,16 +11,26 @@ export interface SlashMenuConfig {
|
|
|
11
11
|
onOpen?: (() => void) | undefined;
|
|
12
12
|
}
|
|
13
13
|
export declare function slashMatches(input: string, commands: SlashCommandOption[]): SlashCommandOption[];
|
|
14
|
-
/** The palette's open state and keys; the caller owns the input.
|
|
14
|
+
/** The palette's open state and keys; the caller owns the input.
|
|
15
|
+
* Base UI's Autocomplete drives a single-line input, and its arrow keys would take the caret
|
|
16
|
+
* from a multi-line composer, so the textarea stays a textbox that points at the list:
|
|
17
|
+
* spread `inputProps` on it. */
|
|
15
18
|
export declare function useSlashMenu(input: string, config: SlashMenuConfig | undefined, setInput: (value: string) => void): {
|
|
16
19
|
open: boolean;
|
|
17
20
|
matches: SlashCommandOption[];
|
|
18
21
|
active: number;
|
|
19
22
|
choose: (name: string) => void;
|
|
20
23
|
handleKey: (e: KeyboardEvent<HTMLTextAreaElement>) => boolean;
|
|
24
|
+
listId: string;
|
|
25
|
+
inputProps: {
|
|
26
|
+
'aria-autocomplete': 'list';
|
|
27
|
+
'aria-controls': string | undefined;
|
|
28
|
+
'aria-activedescendant': string | undefined;
|
|
29
|
+
};
|
|
21
30
|
};
|
|
22
|
-
export declare function SlashMenu({ label, matches, active, onChoose, }: {
|
|
31
|
+
export declare function SlashMenu({ label, listId, matches, active, onChoose, }: {
|
|
23
32
|
label: string;
|
|
33
|
+
listId: string;
|
|
24
34
|
matches: SlashCommandOption[];
|
|
25
35
|
active: number;
|
|
26
36
|
onChoose: (name: string) => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { panelClassName, panelItemClassName } from "../../components/floating.js";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useEffect, useId, useState } from "react";
|
|
4
5
|
//#region src/ai/components/SlashMenu.tsx
|
|
5
6
|
var MAX_SHOWN = 8;
|
|
6
7
|
var TYPING_NAME = /^\/([\w:-]*)$/;
|
|
@@ -10,8 +11,12 @@ function slashMatches(input, commands) {
|
|
|
10
11
|
const query = (typed[1] ?? "").toLowerCase();
|
|
11
12
|
return commands.filter((c) => c.name.toLowerCase().startsWith(query)).slice(0, MAX_SHOWN);
|
|
12
13
|
}
|
|
13
|
-
/** The palette's open state and keys; the caller owns the input.
|
|
14
|
+
/** The palette's open state and keys; the caller owns the input.
|
|
15
|
+
* Base UI's Autocomplete drives a single-line input, and its arrow keys would take the caret
|
|
16
|
+
* from a multi-line composer, so the textarea stays a textbox that points at the list:
|
|
17
|
+
* spread `inputProps` on it. */
|
|
14
18
|
function useSlashMenu(input, config, setInput) {
|
|
19
|
+
const listId = useId();
|
|
15
20
|
const [active, setActive] = useState(0);
|
|
16
21
|
const [dismissed, setDismissed] = useState(false);
|
|
17
22
|
const matches = config ? slashMatches(input, config.commands) : [];
|
|
@@ -30,6 +35,7 @@ function useSlashMenu(input, config, setInput) {
|
|
|
30
35
|
setDismissed(false);
|
|
31
36
|
}
|
|
32
37
|
const choose = (name) => setInput(`/${name} `);
|
|
38
|
+
const shown = Math.min(active, matches.length - 1);
|
|
33
39
|
/** True when the key belonged to the menu. */
|
|
34
40
|
const handleKey = (e) => {
|
|
35
41
|
if (!open) return false;
|
|
@@ -43,7 +49,7 @@ function useSlashMenu(input, config, setInput) {
|
|
|
43
49
|
case "Tab":
|
|
44
50
|
case "Enter": {
|
|
45
51
|
if (e.shiftKey) return false;
|
|
46
|
-
const pick = matches[
|
|
52
|
+
const pick = matches[shown];
|
|
47
53
|
if (!pick) return false;
|
|
48
54
|
choose(pick.name);
|
|
49
55
|
break;
|
|
@@ -59,29 +65,39 @@ function useSlashMenu(input, config, setInput) {
|
|
|
59
65
|
return {
|
|
60
66
|
open,
|
|
61
67
|
matches,
|
|
62
|
-
active,
|
|
68
|
+
active: shown,
|
|
63
69
|
choose,
|
|
64
|
-
handleKey
|
|
70
|
+
handleKey,
|
|
71
|
+
listId,
|
|
72
|
+
inputProps: {
|
|
73
|
+
"aria-autocomplete": "list",
|
|
74
|
+
"aria-controls": open ? listId : void 0,
|
|
75
|
+
"aria-activedescendant": open ? optionId(listId, shown) : void 0
|
|
76
|
+
}
|
|
65
77
|
};
|
|
66
78
|
}
|
|
67
|
-
|
|
79
|
+
var optionId = (listId, index) => `${listId}-${index}`;
|
|
80
|
+
function SlashMenu({ label, listId, matches, active, onChoose }) {
|
|
68
81
|
return /* @__PURE__ */ jsx("div", {
|
|
82
|
+
id: listId,
|
|
69
83
|
role: "listbox",
|
|
70
84
|
"aria-label": label,
|
|
71
85
|
"data-testid": "slash-menu",
|
|
72
|
-
className: "absolute bottom-full left-0 right-0 mb-2
|
|
73
|
-
children: matches.map((c, i) => /* @__PURE__ */ jsxs("
|
|
74
|
-
|
|
86
|
+
className: clsx("absolute bottom-full left-0 right-0 z-20 mb-2 overflow-hidden py-1", panelClassName),
|
|
87
|
+
children: matches.map((c, i) => /* @__PURE__ */ jsxs("div", {
|
|
88
|
+
id: optionId(listId, i),
|
|
75
89
|
role: "option",
|
|
90
|
+
tabIndex: -1,
|
|
76
91
|
"aria-selected": i === active,
|
|
92
|
+
"data-highlighted": i === active || void 0,
|
|
77
93
|
onMouseDown: (e) => e.preventDefault(),
|
|
78
94
|
onClick: () => onChoose(c.name),
|
|
79
|
-
className:
|
|
95
|
+
className: clsx("items-baseline gap-3", panelItemClassName),
|
|
80
96
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
81
|
-
className: "font-mono
|
|
97
|
+
className: "font-mono",
|
|
82
98
|
children: ["/", c.name]
|
|
83
99
|
}), c.description && /* @__PURE__ */ jsx("span", {
|
|
84
|
-
className: "truncate text-xs theme-muted-text",
|
|
100
|
+
className: "truncate text-xs text-(--theme-muted-text-color)",
|
|
85
101
|
children: c.description
|
|
86
102
|
})]
|
|
87
103
|
}, c.name))
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FaStop } from "../../../icons/fa/FaStop.js";
|
|
2
2
|
import { LoaderIcon } from "../../../components/StatusIcons.js";
|
|
3
3
|
import { useChatConfig } from "../../core/config.js";
|
|
4
|
-
import
|
|
5
|
-
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { clsx } from "clsx";
|
|
6
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { useEffect, useRef, useState } from "react";
|
|
7
7
|
import { DateTime } from "luxon";
|
|
8
8
|
//#region src/ai/components/agent/ActivityLine.tsx
|
|
9
9
|
/** The agent status words: one is picked per turn and held until it ends. */
|
|
@@ -142,7 +142,7 @@ function ActivityLine({ startedAt, inputTokens, outputTokens, onStop, stopping =
|
|
|
142
142
|
disabled: stopping,
|
|
143
143
|
"aria-label": strings.input.stopGenerating,
|
|
144
144
|
title: strings.input.stopGenerating,
|
|
145
|
-
className:
|
|
145
|
+
className: clsx("ml-auto inline-flex h-7 items-center gap-1.5 rounded-md px-2 text-xs theme-muted-text transition-colors", "hover:theme-hover hover:theme-text disabled:cursor-not-allowed disabled:opacity-50"),
|
|
146
146
|
children: [/* @__PURE__ */ jsx(FaStop, { className: "h-3 w-3" }), strings.activity.stop]
|
|
147
147
|
})
|
|
148
148
|
]
|
|
@@ -11,14 +11,14 @@ import { useChatConfig } from "../../core/config.js";
|
|
|
11
11
|
import Markdown from "../../ui/Markdown.js";
|
|
12
12
|
import { chatProseClasses } from "../../ui/prose.js";
|
|
13
13
|
import { ReasoningBody, ReasoningToggle } from "../Reasoning.js";
|
|
14
|
-
import
|
|
14
|
+
import { clsx } from "clsx";
|
|
15
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
16
|
import { useEffect, useMemo, useState } from "react";
|
|
16
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
17
17
|
//#region src/ai/components/agent/AgentMessageParts.tsx
|
|
18
18
|
var COLLAPSED_RESULT_LINES = 12;
|
|
19
19
|
function LineSpans({ text, tokens, emphasis }) {
|
|
20
20
|
const pieces = tokens ?? [{ content: text }];
|
|
21
|
-
if (!emphasis || emphasis.length === 0) return /* @__PURE__ */ jsx(Fragment
|
|
21
|
+
if (!emphasis || emphasis.length === 0) return /* @__PURE__ */ jsx(Fragment, { children: pieces.map((t, i) => /* @__PURE__ */ jsx("span", {
|
|
22
22
|
style: t.color ? { color: t.color } : void 0,
|
|
23
23
|
children: t.content
|
|
24
24
|
}, i)) });
|
|
@@ -41,7 +41,7 @@ function LineSpans({ text, tokens, emphasis }) {
|
|
|
41
41
|
}
|
|
42
42
|
offset += t.content.length;
|
|
43
43
|
}
|
|
44
|
-
return /* @__PURE__ */ jsx(Fragment
|
|
44
|
+
return /* @__PURE__ */ jsx(Fragment, { children: out });
|
|
45
45
|
}
|
|
46
46
|
function DiffRows({ rows, lang }) {
|
|
47
47
|
const isDark = useCssIsDark();
|
|
@@ -68,7 +68,7 @@ function DiffRows({ rows, lang }) {
|
|
|
68
68
|
return /* @__PURE__ */ jsx("div", {
|
|
69
69
|
className: "overflow-x-auto rounded-md border theme-border font-mono text-xs leading-5",
|
|
70
70
|
children: rows.map((row, i) => /* @__PURE__ */ jsxs("div", {
|
|
71
|
-
className:
|
|
71
|
+
className: clsx("flex whitespace-pre", row.kind === "add" && "bg-green-500/15", row.kind === "del" && "bg-red-500/15", row.kind === "gap" && "theme-muted-text"),
|
|
72
72
|
children: [
|
|
73
73
|
numbered && /* @__PURE__ */ jsx("span", {
|
|
74
74
|
className: "w-10 shrink-0 select-none text-right pr-2 theme-muted-text",
|
|
@@ -207,11 +207,11 @@ function ToolCallBlock({ part }) {
|
|
|
207
207
|
]
|
|
208
208
|
})]
|
|
209
209
|
}),
|
|
210
|
-
/* @__PURE__ */ jsx(LuChevronRight, { className:
|
|
210
|
+
/* @__PURE__ */ jsx(LuChevronRight, { className: clsx("w-3.5 h-3.5 mt-1 shrink-0 theme-muted-text transition-transform", expanded && "rotate-90") })
|
|
211
211
|
]
|
|
212
212
|
}),
|
|
213
213
|
!isDiff && /* @__PURE__ */ jsx("div", {
|
|
214
|
-
className:
|
|
214
|
+
className: clsx("ml-5 mt-0.5 text-[13px]", part.status === "error" ? "text-red-600" : "theme-muted-text"),
|
|
215
215
|
children: expanded ? null : summary
|
|
216
216
|
}),
|
|
217
217
|
expanded && !isDiff && /* @__PURE__ */ jsxs("div", {
|
|
@@ -251,7 +251,7 @@ function SubagentCard({ part }) {
|
|
|
251
251
|
className: "flex min-h-6 items-start gap-2 w-full text-left",
|
|
252
252
|
children: [
|
|
253
253
|
part.status === "running" ? /* @__PURE__ */ jsx(LoaderIcon, { className: "w-3.5 h-3.5 mt-[3px] animate-spin theme-muted-text" }) : /* @__PURE__ */ jsx("span", {
|
|
254
|
-
className:
|
|
254
|
+
className: clsx("leading-none", part.status === "failed" ? "text-red-500" : "text-green-600"),
|
|
255
255
|
style: color && part.status !== "failed" ? { color } : void 0,
|
|
256
256
|
children: "●"
|
|
257
257
|
}),
|
|
@@ -269,10 +269,10 @@ function SubagentCard({ part }) {
|
|
|
269
269
|
]
|
|
270
270
|
})]
|
|
271
271
|
}),
|
|
272
|
-
canExpand && /* @__PURE__ */ jsx(LuChevronRight, { className:
|
|
272
|
+
canExpand && /* @__PURE__ */ jsx(LuChevronRight, { className: clsx("w-3.5 h-3.5 mt-1 shrink-0 theme-muted-text transition-transform", expanded && "rotate-90") })
|
|
273
273
|
]
|
|
274
274
|
}), /* @__PURE__ */ jsx("div", {
|
|
275
|
-
className:
|
|
275
|
+
className: clsx("ml-5 mt-0.5 text-[13px]", part.status === "failed" ? "text-red-600" : "theme-muted-text"),
|
|
276
276
|
children: expanded ? /* @__PURE__ */ jsxs("div", {
|
|
277
277
|
className: "space-y-1",
|
|
278
278
|
children: [actions.length > 0 && /* @__PURE__ */ jsxs("ul", {
|
|
@@ -297,7 +297,7 @@ function ConfirmApproval({ part, onAnswer }) {
|
|
|
297
297
|
path: [t.allowPath, t.denyPath],
|
|
298
298
|
call: [t.allowCall, t.denyCall]
|
|
299
299
|
}[part.subject ?? "command"];
|
|
300
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
300
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
301
301
|
part.command && /* @__PURE__ */ jsx("pre", {
|
|
302
302
|
className: "overflow-x-auto rounded-md bg-(--theme-muted-panel-bg) p-2 font-mono text-xs whitespace-pre-wrap",
|
|
303
303
|
children: part.command
|
|
@@ -376,7 +376,7 @@ function AskApproval({ part, onAnswer }) {
|
|
|
376
376
|
kind: "ask",
|
|
377
377
|
text
|
|
378
378
|
});
|
|
379
|
-
if (!onAnswer) return /* @__PURE__ */ jsxs(Fragment
|
|
379
|
+
if (!onAnswer) return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
380
380
|
part.question && /* @__PURE__ */ jsx("div", {
|
|
381
381
|
className: "text-sm",
|
|
382
382
|
children: part.question
|
|
@@ -393,7 +393,7 @@ function AskApproval({ part, onAnswer }) {
|
|
|
393
393
|
children: t.approvalPending
|
|
394
394
|
})
|
|
395
395
|
] });
|
|
396
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
396
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [part.question && /* @__PURE__ */ jsx("div", {
|
|
397
397
|
className: "text-sm",
|
|
398
398
|
children: part.question
|
|
399
399
|
}), own === null ? /* @__PURE__ */ jsxs("div", {
|
|
@@ -457,7 +457,7 @@ function ApprovalBlock({ part, onApprovalAnswer }) {
|
|
|
457
457
|
function PlanApproval({ part }) {
|
|
458
458
|
const { strings } = useChatConfig();
|
|
459
459
|
const t = strings.agentTranscript;
|
|
460
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
460
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
461
461
|
className: "text-xs theme-muted-text",
|
|
462
462
|
children: t.planPending
|
|
463
463
|
}), part.plan && /* @__PURE__ */ jsx("div", {
|
|
@@ -480,7 +480,7 @@ function TodoSnapshotBlock({ part }) {
|
|
|
480
480
|
}), /* @__PURE__ */ jsx("ul", {
|
|
481
481
|
className: "space-y-0.5 text-sm",
|
|
482
482
|
children: part.todos.map((todo) => /* @__PURE__ */ jsxs("li", {
|
|
483
|
-
className:
|
|
483
|
+
className: clsx("flex items-start gap-2", todo.status === "completed" && "line-through theme-muted-text", todo.status === "in_progress" && "font-semibold"),
|
|
484
484
|
children: [/* @__PURE__ */ jsx("span", {
|
|
485
485
|
className: "select-none font-mono",
|
|
486
486
|
children: todo.status === "completed" ? "✔" : todo.status === "in_progress" ? "■" : "□"
|
|
@@ -508,7 +508,7 @@ function NoticeBlock({ part }) {
|
|
|
508
508
|
children: [/* @__PURE__ */ jsx("span", {
|
|
509
509
|
className: "min-w-0 flex-1 whitespace-pre-wrap",
|
|
510
510
|
children: part.text
|
|
511
|
-
}), /* @__PURE__ */ jsx(LuChevronRight, { className:
|
|
511
|
+
}), /* @__PURE__ */ jsx(LuChevronRight, { className: clsx("mt-0.5 h-3.5 w-3.5 shrink-0 transition-transform", expanded && "rotate-90") })]
|
|
512
512
|
}), expanded && /* @__PURE__ */ jsx("div", {
|
|
513
513
|
className: "ml-4 mt-1 border-l-2 theme-border pl-3 text-sm theme-muted-text",
|
|
514
514
|
children: /* @__PURE__ */ jsx(Markdown, { children: part.detail })
|
|
@@ -516,7 +516,7 @@ function NoticeBlock({ part }) {
|
|
|
516
516
|
});
|
|
517
517
|
}
|
|
518
518
|
return /* @__PURE__ */ jsx("div", {
|
|
519
|
-
className:
|
|
519
|
+
className: clsx("my-1 text-xs rounded-md px-2.5 py-1.5", part.kind === "error" ? "bg-red-500/10 text-red-700" : "bg-yellow-500/10 text-yellow-700"),
|
|
520
520
|
"data-testid": `${part.kind}-part`,
|
|
521
521
|
children: part.text
|
|
522
522
|
});
|
|
@@ -575,7 +575,7 @@ function ReasoningBlock({ part, isStreaming }) {
|
|
|
575
575
|
}
|
|
576
576
|
function TextBlock({ part, isStreaming }) {
|
|
577
577
|
return /* @__PURE__ */ jsx("div", {
|
|
578
|
-
className:
|
|
578
|
+
className: clsx(chatProseClasses, "[&:not(:first-child)]:mt-4"),
|
|
579
579
|
children: /* @__PURE__ */ jsx(Markdown, {
|
|
580
580
|
isStreaming: isStreaming ?? false,
|
|
581
581
|
children: part.text
|
|
@@ -702,10 +702,10 @@ function RollupGroup({ members, message }) {
|
|
|
702
702
|
className: "font-mono text-[13px] theme-muted-text min-w-0 truncate",
|
|
703
703
|
children: sentence
|
|
704
704
|
}),
|
|
705
|
-
/* @__PURE__ */ jsx(LuChevronRight, { className:
|
|
705
|
+
/* @__PURE__ */ jsx(LuChevronRight, { className: clsx("w-3.5 h-3.5 shrink-0 theme-muted-text transition-transform", expanded && "rotate-90") })
|
|
706
706
|
]
|
|
707
707
|
}), /* @__PURE__ */ jsx("div", {
|
|
708
|
-
className:
|
|
708
|
+
className: clsx("ml-1.5 mt-0.5 rounded-md", expanded ? "bg-(--theme-muted-panel-bg)/40 px-2" : "hidden"),
|
|
709
709
|
children: members.map((m) => /* @__PURE__ */ jsx(PartDispatch, {
|
|
710
710
|
part: m.part,
|
|
711
711
|
message
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { Select } from "../../../components/Select.js";
|
|
1
2
|
import { isNamedPermissionMode, permissionModesUpTo } from "../../agent/permissions.js";
|
|
2
3
|
import { useChatConfig } from "../../core/config.js";
|
|
3
|
-
import
|
|
4
|
+
import { smallChipClassName } from "../../ui/chip.js";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
//#region src/ai/components/agent/PermissionPicker.tsx
|
|
6
7
|
var LABEL_KEY = {
|
|
@@ -17,22 +18,23 @@ function PermissionPicker({ mode, onPick, ceiling, accepted, disabled = false })
|
|
|
17
18
|
const t = useChatConfig().strings.permissions;
|
|
18
19
|
const current = mode ?? "accept-edits";
|
|
19
20
|
const named = isNamedPermissionMode(current) ? current : void 0;
|
|
20
|
-
const
|
|
21
|
+
const items = permissionModesUpTo(ceiling, accepted).map((m) => ({
|
|
21
22
|
value: m,
|
|
22
23
|
label: t[LABEL_KEY[m]],
|
|
23
24
|
description: t[`${LABEL_KEY[m]}Hint`]
|
|
24
25
|
}));
|
|
25
|
-
return /* @__PURE__ */ jsx(
|
|
26
|
-
|
|
26
|
+
return /* @__PURE__ */ jsx(Select, {
|
|
27
|
+
"aria-label": t.choose,
|
|
28
|
+
items,
|
|
27
29
|
value: current,
|
|
28
|
-
|
|
30
|
+
onValueChange: (value) => value && onPick(value),
|
|
29
31
|
disabled,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
triggerTooltip: named ? t[`${LABEL_KEY[named]}Hint`] : void 0,
|
|
33
|
+
trigger: /* @__PURE__ */ jsx("button", {
|
|
34
|
+
type: "button",
|
|
35
|
+
className: smallChipClassName,
|
|
36
|
+
children: named ? t[LABEL_KEY[named]] : current
|
|
37
|
+
})
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
//#endregion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import { type OpenMenu
|
|
2
|
+
import { type OpenMenu } from '../../components/ContextMenu.js';
|
|
3
|
+
import type { MenuEntry } from '../../components/MenuEntries.js';
|
|
3
4
|
import type { ConversationSummary } from '../types.js';
|
|
4
5
|
export type ConversationGroupKey = 'groupToday' | 'groupYesterday' | 'groupThisWeek' | 'groupThisMonth' | 'groupOlder';
|
|
5
6
|
/** Conversations by how long ago they started, newest group first, leaving
|
|
@@ -13,11 +14,8 @@ export declare function groupConversationsByDate<T extends {
|
|
|
13
14
|
/** What a conversation row offers behind its menu (rename, share, download,
|
|
14
15
|
* delete) and the menu and dialogs that carry them out, for any list of
|
|
15
16
|
* conversations. Render `overlays` once beside the list. */
|
|
16
|
-
export declare function useConversationActions(
|
|
17
|
-
|
|
18
|
-
menuZClassName?: string;
|
|
19
|
-
}): {
|
|
20
|
-
menuItems: (conv: ConversationSummary) => RowMenuItem[];
|
|
17
|
+
export declare function useConversationActions(): {
|
|
18
|
+
menuItems: (conv: ConversationSummary) => MenuEntry[];
|
|
21
19
|
openMenu: OpenMenu;
|
|
22
20
|
overlays: ReactNode;
|
|
23
21
|
};
|
|
@@ -2,14 +2,14 @@ import { BiSolidTrashAlt } from "../../icons/bi/BiSolidTrashAlt.js";
|
|
|
2
2
|
import { FaCloudDownloadAlt } from "../../icons/fa/FaCloudDownloadAlt.js";
|
|
3
3
|
import { FaEdit } from "../../icons/fa/FaEdit.js";
|
|
4
4
|
import { PiShareBold } from "../../icons/pi/PiShareBold.js";
|
|
5
|
-
import {
|
|
5
|
+
import { useContextMenu } from "../../components/ContextMenu.js";
|
|
6
6
|
import { useChatConfig } from "../core/config.js";
|
|
7
7
|
import { useChat } from "../core/ChatProvider.js";
|
|
8
8
|
import { useRowDialogs } from "../ui/sidebar.js";
|
|
9
9
|
import { conversationToMarkdown, downloadText, exportFilename } from "../core/exportConversation.js";
|
|
10
10
|
import ShareDialog from "./ShareDialog.js";
|
|
11
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import { useState } from "react";
|
|
12
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { DateTime } from "luxon";
|
|
14
14
|
//#region src/ai/components/conversationActions.tsx
|
|
15
15
|
/** Conversations by how long ago they started, newest group first, leaving
|
|
@@ -35,11 +35,11 @@ function groupConversationsByDate(conversations) {
|
|
|
35
35
|
/** What a conversation row offers behind its menu (rename, share, download,
|
|
36
36
|
* delete) and the menu and dialogs that carry them out, for any list of
|
|
37
37
|
* conversations. Render `overlays` once beside the list. */
|
|
38
|
-
function useConversationActions(
|
|
38
|
+
function useConversationActions() {
|
|
39
39
|
const { strings } = useChatConfig();
|
|
40
40
|
const t = strings.sidebar;
|
|
41
41
|
const { adapter, notify, deleteConversation, updateConversationTitle } = useChat();
|
|
42
|
-
const { openMenu, contextMenu } =
|
|
42
|
+
const { openMenu, contextMenu } = useContextMenu();
|
|
43
43
|
const [sharing, setSharing] = useState(null);
|
|
44
44
|
const { requestDelete, requestRename, dialogs } = useRowDialogs({
|
|
45
45
|
strings: {
|
|
@@ -65,35 +65,31 @@ function useConversationActions({ menuZClassName } = {}) {
|
|
|
65
65
|
};
|
|
66
66
|
const menuItems = (conv) => [
|
|
67
67
|
{
|
|
68
|
-
kind: "action",
|
|
69
68
|
label: t.rename,
|
|
70
69
|
icon: /* @__PURE__ */ jsx(FaEdit, {}),
|
|
71
|
-
|
|
70
|
+
onClick: () => requestRename(conv)
|
|
72
71
|
},
|
|
73
72
|
...adapter.sharing && conv.isOwner !== false ? [{
|
|
74
|
-
kind: "action",
|
|
75
73
|
label: t.share,
|
|
76
74
|
icon: /* @__PURE__ */ jsx(PiShareBold, {}),
|
|
77
|
-
|
|
75
|
+
onClick: () => setSharing(conv.id)
|
|
78
76
|
}] : [],
|
|
79
77
|
{
|
|
80
|
-
kind: "action",
|
|
81
78
|
label: strings.chrome.download,
|
|
82
79
|
icon: /* @__PURE__ */ jsx(FaCloudDownloadAlt, {}),
|
|
83
|
-
|
|
80
|
+
onClick: () => void download(conv.id)
|
|
84
81
|
},
|
|
85
82
|
{
|
|
86
|
-
kind: "action",
|
|
87
83
|
label: t.delete,
|
|
88
84
|
icon: /* @__PURE__ */ jsx(BiSolidTrashAlt, {}),
|
|
89
85
|
destructive: true,
|
|
90
|
-
|
|
86
|
+
onClick: () => requestDelete(conv)
|
|
91
87
|
}
|
|
92
88
|
];
|
|
93
89
|
return {
|
|
94
90
|
menuItems,
|
|
95
91
|
openMenu,
|
|
96
|
-
overlays: /* @__PURE__ */ jsxs(Fragment
|
|
92
|
+
overlays: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
97
93
|
contextMenu,
|
|
98
94
|
dialogs,
|
|
99
95
|
sharing && /* @__PURE__ */ jsx(ShareDialog, {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { applyPartDelta, finalizeParts } from "./parts.js";
|
|
1
|
+
import { applyPartDelta, finalizeParts, toolTurnMessages } from "./parts.js";
|
|
2
2
|
import { chatReducer, initialState } from "./chatReducer.js";
|
|
3
3
|
import { ChatConfigProvider, resolveChatConfig } from "./config.js";
|
|
4
4
|
import { providerIssueFor } from "./providerIssues.js";
|
|
5
5
|
import { ReportSidebarPresentationContext, readStoredSidebar, storeSidebar, useControllable } from "./sidebarState.js";
|
|
6
6
|
import { useSSEStream } from "./useSSEStream.js";
|
|
7
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
8
7
|
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
9
9
|
import { DateTime } from "luxon";
|
|
10
10
|
//#region src/ai/core/ChatProvider.tsx
|
|
11
11
|
var SELECTED_MODEL_STORAGE_KEY = "aiChatSelectedModel";
|
|
@@ -392,7 +392,7 @@ function ChatProvider({ adapter, currentUser, navigation, notify, activeConversa
|
|
|
392
392
|
});
|
|
393
393
|
};
|
|
394
394
|
const apiMessages = [
|
|
395
|
-
...(isNewConversation ? [] : state.currentConversation?.messages || []).filter((m) => m.content || m.toolCalls?.length).
|
|
395
|
+
...(isNewConversation ? [] : state.currentConversation?.messages || []).filter((m) => m.content || m.toolCalls?.length || m.parts?.length).flatMap((m) => {
|
|
396
396
|
const msg = {
|
|
397
397
|
role: m.role,
|
|
398
398
|
content: m.content || null
|
|
@@ -401,7 +401,7 @@ function ChatProvider({ adapter, currentUser, navigation, notify, activeConversa
|
|
|
401
401
|
if (m.role === "assistant" && m.toolCalls?.length) msg.tool_calls = m.toolCalls;
|
|
402
402
|
if (m.role === "assistant" && m.responsesOutput?.length && m.model === state.selectedProvider) msg.responses_output = m.responsesOutput;
|
|
403
403
|
if (m.role === "tool" && m.toolCallId) msg.tool_call_id = m.toolCallId;
|
|
404
|
-
return msg;
|
|
404
|
+
return m.role === "assistant" ? toolTurnMessages(m.parts, msg) : [msg];
|
|
405
405
|
}),
|
|
406
406
|
...precedingApiMessages,
|
|
407
407
|
{
|
package/dist/ai/core/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { safeUrl } from "../../safeUrl.js";
|
|
2
2
|
import { defaultChatStrings } from "../strings.js";
|
|
3
|
-
import { createContext, useContext } from "react";
|
|
4
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
5
|
//#region src/ai/core/config.tsx
|
|
6
6
|
function hrefFor(target) {
|
|
7
7
|
switch (target.kind) {
|
package/dist/ai/core/parts.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CompletionMessage } from '../adapter/openai/wire.js';
|
|
1
2
|
import type { PartDelta } from '../adapter/types.js';
|
|
2
3
|
import type { MessagePart } from '../types.js';
|
|
3
4
|
/** Fold one streamed PartDelta into a parts timeline. Pure: returns a new
|
|
@@ -5,6 +6,10 @@ import type { MessagePart } from '../types.js';
|
|
|
5
6
|
* and the provider's local accumulation. Unknown target ids are dropped
|
|
6
7
|
* rather than invented — an end without a start has nothing to render. */
|
|
7
8
|
export declare function applyPartDelta(parts: MessagePart[], delta: PartDelta): MessagePart[];
|
|
9
|
+
/** The wire history for an assistant turn whose tool calls the gateway ran:
|
|
10
|
+
* the calls, each result, then the answer. A turn with no finished tool
|
|
11
|
+
* calls comes back as the answer alone. */
|
|
12
|
+
export declare function toolTurnMessages(parts: MessagePart[] | null | undefined, answer: CompletionMessage): CompletionMessage[];
|
|
8
13
|
/** A turn can end (completed or stopped) with tool calls still marked
|
|
9
14
|
* running — the transport died before their tool_end arrived. A stored
|
|
10
15
|
* message must not spin forever, so close them out as interrupted. */
|