@parallelworks/ui 0.76.0 → 0.78.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.
Files changed (270) hide show
  1. package/README.md +30 -5
  2. package/dist/access/AccessDrawer.d.ts +28 -7
  3. package/dist/access/AccessDrawer.js +216 -35
  4. package/dist/access/AccessList.d.ts +19 -1
  5. package/dist/access/AccessList.js +220 -9
  6. package/dist/access/GrantView.d.ts +3 -1
  7. package/dist/access/GrantView.js +17 -4
  8. package/dist/access/PrincipalPicker.js +5 -5
  9. package/dist/access/focus.js +1 -1
  10. package/dist/access/index.d.ts +2 -2
  11. package/dist/access/index.js +2 -2
  12. package/dist/access/strings.d.ts +18 -0
  13. package/dist/access/strings.js +20 -2
  14. package/dist/access/types.d.ts +26 -0
  15. package/dist/ai/adapter/types.d.ts +1 -0
  16. package/dist/ai/components/AllocationSelector.js +1 -1
  17. package/dist/ai/components/AttachmentManager.js +5 -5
  18. package/dist/ai/components/AttachmentUpload.js +2 -2
  19. package/dist/ai/components/BranchNavigator.js +1 -1
  20. package/dist/ai/components/ChatActivity.d.ts +2 -0
  21. package/dist/ai/components/ChatActivity.js +31 -0
  22. package/dist/ai/components/ChatEmptyState.js +3 -3
  23. package/dist/ai/components/ChatInput.js +3 -5
  24. package/dist/ai/components/ChatLayout.js +1 -1
  25. package/dist/ai/components/ChatMessage.js +1 -1
  26. package/dist/ai/components/ChatMessageList.js +2 -2
  27. package/dist/ai/components/ChatSidebar.js +3 -3
  28. package/dist/ai/components/ChatThread.js +4 -4
  29. package/dist/ai/components/ComposerAddMenu.js +9 -20
  30. package/dist/ai/components/ModelSelector.js +3 -3
  31. package/dist/ai/components/PastedText.js +5 -5
  32. package/dist/ai/components/SessionView.js +5 -2
  33. package/dist/ai/components/ShareDialog.js +3 -3
  34. package/dist/ai/components/SlashMenu.d.ts +31 -4
  35. package/dist/ai/components/SlashMenu.js +36 -63
  36. package/dist/ai/components/agent/ActivityLine.js +1 -1
  37. package/dist/ai/components/agent/AgentMessageParts.d.ts +1 -1
  38. package/dist/ai/components/agent/AgentMessageParts.js +44 -18
  39. package/dist/ai/components/conversationActions.js +3 -3
  40. package/dist/ai/core/ChatProvider.js +11 -2
  41. package/dist/ai/core/config.d.ts +10 -1
  42. package/dist/ai/core/config.js +1 -1
  43. package/dist/ai/index.d.ts +1 -1
  44. package/dist/ai/strings.d.ts +2 -0
  45. package/dist/ai/strings.js +2 -1
  46. package/dist/ai/types.d.ts +3 -0
  47. package/dist/ai/ui/ConversationSidebar.js +3 -3
  48. package/dist/ai/ui/sidebar.js +3 -3
  49. package/dist/assets/yaml.worker-DOBV2lND.js +884 -0
  50. package/dist/components/ActionMenu.d.ts +38 -9
  51. package/dist/components/ActionMenu.js +48 -22
  52. package/dist/components/Avatar.d.ts +66 -6
  53. package/dist/components/Avatar.js +130 -18
  54. package/dist/components/Breadcrumbs.d.ts +4 -0
  55. package/dist/components/Breadcrumbs.js +26 -10
  56. package/dist/components/Button.d.ts +3 -2
  57. package/dist/components/Button.js +11 -1
  58. package/dist/components/Callout.d.ts +3 -2
  59. package/dist/components/Callout.js +3 -2
  60. package/dist/components/Card.d.ts +33 -9
  61. package/dist/components/Card.js +24 -8
  62. package/dist/components/Checkbox.d.ts +3 -1
  63. package/dist/components/Checkbox.js +4 -2
  64. package/dist/components/ColorInput.js +1 -1
  65. package/dist/components/Combobox.d.ts +23 -0
  66. package/dist/components/Combobox.js +252 -86
  67. package/dist/components/ConfirmModal.d.ts +26 -2
  68. package/dist/components/ConfirmModal.js +81 -15
  69. package/dist/components/ContextMenu.d.ts +29 -2
  70. package/dist/components/ContextMenu.js +60 -8
  71. package/dist/components/CopyButton.d.ts +21 -8
  72. package/dist/components/CopyButton.js +29 -9
  73. package/dist/components/CreateModal.d.ts +16 -4
  74. package/dist/components/CreateModal.js +27 -16
  75. package/dist/components/DatePicker.d.ts +31 -1
  76. package/dist/components/DatePicker.js +178 -47
  77. package/dist/components/DescriptionList.d.ts +13 -3
  78. package/dist/components/DescriptionList.js +43 -11
  79. package/dist/components/Disclosure.d.ts +10 -2
  80. package/dist/components/Disclosure.js +18 -7
  81. package/dist/components/Drawer.js +5 -5
  82. package/dist/components/EmptyState.d.ts +12 -4
  83. package/dist/components/EmptyState.js +18 -10
  84. package/dist/components/ErrorPage.d.ts +40 -0
  85. package/dist/components/ErrorPage.js +101 -0
  86. package/dist/components/ExternalLink.d.ts +4 -1
  87. package/dist/components/ExternalLink.js +4 -5
  88. package/dist/components/Field.d.ts +21 -6
  89. package/dist/components/Field.js +32 -16
  90. package/dist/components/FileButton.d.ts +19 -0
  91. package/dist/components/FileButton.js +32 -0
  92. package/dist/components/HoverCard.d.ts +26 -6
  93. package/dist/components/HoverCard.js +11 -5
  94. package/dist/components/IconButton.js +4 -2
  95. package/dist/components/InfoTip.js +3 -3
  96. package/dist/components/Input.d.ts +33 -3
  97. package/dist/components/Input.js +149 -14
  98. package/dist/components/Kbd.d.ts +40 -0
  99. package/dist/components/Kbd.js +168 -0
  100. package/dist/components/Listbox.d.ts +103 -0
  101. package/dist/components/Listbox.js +190 -0
  102. package/dist/components/Loader.d.ts +8 -2
  103. package/dist/components/Loader.js +16 -1
  104. package/dist/components/Markdown.js +1 -1
  105. package/dist/components/MarkdownImpl.js +1 -1
  106. package/dist/components/Menu.d.ts +20 -2
  107. package/dist/components/Menu.js +48 -19
  108. package/dist/components/MenuEntries.d.ts +38 -2
  109. package/dist/components/MenuEntries.js +266 -39
  110. package/dist/components/Meter.d.ts +50 -11
  111. package/dist/components/Meter.js +71 -21
  112. package/dist/components/Modal.d.ts +9 -3
  113. package/dist/components/Modal.js +68 -29
  114. package/dist/components/OneTimeCodeInput.js +1 -1
  115. package/dist/components/PageHeader.js +111 -7
  116. package/dist/components/PageHeaderAction.d.ts +8 -3
  117. package/dist/components/PageHeaderAction.js +122 -34
  118. package/dist/components/Pagination.d.ts +13 -1
  119. package/dist/components/Pagination.js +90 -19
  120. package/dist/components/Popover.d.ts +13 -2
  121. package/dist/components/Popover.js +20 -21
  122. package/dist/components/Provider.d.ts +140 -3
  123. package/dist/components/Provider.js +142 -12
  124. package/dist/components/RefreshButton.d.ts +13 -6
  125. package/dist/components/RefreshButton.js +17 -9
  126. package/dist/components/RunStatusIcon.d.ts +16 -7
  127. package/dist/components/RunStatusIcon.js +21 -8
  128. package/dist/components/Section.d.ts +11 -4
  129. package/dist/components/Section.js +33 -22
  130. package/dist/components/SegmentedControl.d.ts +16 -3
  131. package/dist/components/SegmentedControl.js +7 -3
  132. package/dist/components/Select.d.ts +19 -3
  133. package/dist/components/Select.js +114 -68
  134. package/dist/components/SelectionCopy.d.ts +10 -0
  135. package/dist/components/SelectionCopy.js +105 -0
  136. package/dist/components/SettingModeOption.js +1 -1
  137. package/dist/components/SettingsCard.js +1 -1
  138. package/dist/components/Skeleton.js +1 -1
  139. package/dist/components/StatusBadge.d.ts +55 -10
  140. package/dist/components/StatusBadge.js +91 -15
  141. package/dist/components/StickyBar.js +1 -1
  142. package/dist/components/Table.d.ts +22 -4
  143. package/dist/components/Table.js +46 -24
  144. package/dist/components/Tabs.d.ts +9 -4
  145. package/dist/components/Tabs.js +9 -4
  146. package/dist/components/Tag.d.ts +49 -0
  147. package/dist/components/Tag.js +199 -0
  148. package/dist/components/ThemeEditor.js +1 -1
  149. package/dist/components/Toast.js +1 -1
  150. package/dist/components/ToggleGroup.d.ts +4 -1
  151. package/dist/components/ToggleGroup.js +30 -13
  152. package/dist/components/Tooltip.d.ts +9 -3
  153. package/dist/components/Tooltip.js +55 -39
  154. package/dist/components/buttonClasses.d.ts +5 -2
  155. package/dist/components/buttonClasses.js +11 -10
  156. package/dist/components/chart.d.ts +69 -0
  157. package/dist/components/chart.js +145 -0
  158. package/dist/components/comboboxItems.d.ts +7 -1
  159. package/dist/components/comboboxItems.js +6 -2
  160. package/dist/components/dismiss.d.ts +5 -1
  161. package/dist/components/dismiss.js +6 -2
  162. package/dist/components/floating.d.ts +4 -4
  163. package/dist/components/floating.js +5 -5
  164. package/dist/components/headerActionsFit.d.ts +37 -0
  165. package/dist/components/headerActionsFit.js +81 -0
  166. package/dist/components/pageHeaderStore.d.ts +3 -0
  167. package/dist/components/pageHeaderStore.js +3 -0
  168. package/dist/components/pathBreaks.js +2 -2
  169. package/dist/components/popupContainer.d.ts +17 -0
  170. package/dist/components/popupContainer.js +69 -0
  171. package/dist/components/relativeTime.d.ts +21 -10
  172. package/dist/components/relativeTime.js +50 -22
  173. package/dist/components/segmented.d.ts +18 -4
  174. package/dist/components/segmented.js +48 -6
  175. package/dist/components/typedDate.d.ts +5 -0
  176. package/dist/components/typedDate.js +50 -0
  177. package/dist/components/useClosingValue.d.ts +4 -0
  178. package/dist/components/useClosingValue.js +12 -0
  179. package/dist/components/useCopy.d.ts +6 -0
  180. package/dist/components/useCopy.js +3 -3
  181. package/dist/components/useNarrow.d.ts +2 -0
  182. package/dist/components/useNarrow.js +16 -0
  183. package/dist/editor/Editor.js +1 -1
  184. package/dist/editor/FormCodePanel.js +1 -1
  185. package/dist/editor/Monaco.js +1 -1
  186. package/dist/editor/workers.js +1 -1
  187. package/dist/file-explorer/FileExplorer.js +16 -15
  188. package/dist/file-explorer/FileExplorerContext.js +2 -2
  189. package/dist/file-explorer/FilePreview/Viewer.js +3 -3
  190. package/dist/file-explorer/FilePreview/index.js +2 -2
  191. package/dist/file-explorer/FileRowsWindow.js +3 -3
  192. package/dist/file-explorer/FileTable.js +1 -1
  193. package/dist/file-explorer/LoadMoreRow.js +1 -1
  194. package/dist/file-explorer/TreeView.js +5 -5
  195. package/dist/file-explorer/helpers.js +2 -2
  196. package/dist/file-explorer/toasts.js +2 -2
  197. package/dist/form/Fields/CheckboxGroupField.js +1 -1
  198. package/dist/form/Fields/DropdownField.js +1 -1
  199. package/dist/form/Fields/DurationField.js +2 -2
  200. package/dist/form/Fields/MultiDropdownField.js +1 -1
  201. package/dist/form/Fields/NumberField.js +1 -1
  202. package/dist/form/Fields/ObjectField.js +1 -1
  203. package/dist/form/Fields/RangeField.js +1 -1
  204. package/dist/form/Fields/StringField.js +1 -1
  205. package/dist/form/Form.js +3 -3
  206. package/dist/form/FormLayout.js +1 -1
  207. package/dist/form/Wizard/WizardContainer.js +1 -1
  208. package/dist/form/Wizard/WizardNavigation.js +1 -1
  209. package/dist/form/Wizard/WizardStepContent.js +1 -1
  210. package/dist/form/fieldRegistry.js +1 -1
  211. package/dist/form/formEditing.js +1 -1
  212. package/dist/format.d.ts +17 -7
  213. package/dist/format.js +39 -16
  214. package/dist/graph/AnnotationBanner.js +2 -2
  215. package/dist/graph/Connectors.js +5 -5
  216. package/dist/graph/DependencyGraph.js +10 -9
  217. package/dist/graph/GraphEditor.js +4 -4
  218. package/dist/graph/GraphEditorDialogs.js +13 -12
  219. package/dist/graph/GraphNode.js +1 -1
  220. package/dist/graph/InputDialog.js +5 -5
  221. package/dist/graph/InputsEditor.js +7 -7
  222. package/dist/graph/MatrixGroup.js +2 -2
  223. package/dist/graph/ProblemsButton.js +3 -3
  224. package/dist/graph/Reveal.js +1 -1
  225. package/dist/graph/RunWarningsList.js +1 -1
  226. package/dist/graph/ShortcutsButton.js +25 -8
  227. package/dist/graph/StepSummaries.js +1 -1
  228. package/dist/graph/TreeView.js +2 -2
  229. package/dist/graph/WorkflowSettingsDialog.js +3 -3
  230. package/dist/graph/editorFields.js +3 -3
  231. package/dist/graph/editorPrimitives.js +1 -1
  232. package/dist/graph/editorRows.js +5 -5
  233. package/dist/graph/fieldProblems.js +2 -2
  234. package/dist/graph/inputRefs.js +7 -6
  235. package/dist/graph/stepWith.js +2 -2
  236. package/dist/index.d.ts +30 -21
  237. package/dist/index.js +20 -12
  238. package/dist/list/ActionToolbar.d.ts +4 -0
  239. package/dist/list/ActionToolbar.js +35 -12
  240. package/dist/list/ListFilterBar.d.ts +42 -0
  241. package/dist/list/ListFilterBar.js +789 -0
  242. package/dist/list/ListPage.d.ts +42 -4
  243. package/dist/list/ListPage.js +56 -22
  244. package/dist/list/ListTable.d.ts +27 -3
  245. package/dist/list/ListTable.js +48 -23
  246. package/dist/list/ListToolbar.d.ts +31 -0
  247. package/dist/list/ListToolbar.js +43 -0
  248. package/dist/list/ListViewControls.d.ts +8 -4
  249. package/dist/list/ListViewControls.js +22 -14
  250. package/dist/list/UserHoverCard.d.ts +8 -2
  251. package/dist/list/UserHoverCard.js +26 -13
  252. package/dist/list/filterModel.d.ts +122 -0
  253. package/dist/list/filterModel.js +308 -0
  254. package/dist/list/index.d.ts +6 -2
  255. package/dist/list/index.js +6 -2
  256. package/dist/list/listSearch.d.ts +1 -1
  257. package/dist/list/listSearch.js +8 -4
  258. package/dist/list/listView.d.ts +24 -2
  259. package/dist/list/listView.js +47 -45
  260. package/dist/list/rowMenu.d.ts +10 -5
  261. package/dist/list/rowMenu.js +17 -7
  262. package/dist/list/useListFilters.d.ts +68 -0
  263. package/dist/list/useListFilters.js +252 -0
  264. package/dist/logviewer/LogViewer.js +4 -4
  265. package/dist/styles/theme.css +94 -0
  266. package/dist/styles.css +1 -1
  267. package/package.json +11 -11
  268. package/dist/assets/yaml.worker-k9AdOqzf.js +0 -1441
  269. package/dist/components/fullscreen.d.ts +0 -4
  270. package/dist/components/fullscreen.js +0 -18
@@ -17,14 +17,14 @@ import { useChatConfig } from "../../core/config.js";
17
17
  import Markdown from "../../ui/Markdown.js";
18
18
  import { chatProseClasses } from "../../ui/prose.js";
19
19
  import { Reasoning, ReasoningBody } from "../Reasoning.js";
20
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
21
20
  import { memo, useEffect, useId, useMemo, useState } from "react";
21
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
22
22
  import { DateTime } from "luxon";
23
23
  //#region src/ai/components/agent/AgentMessageParts.tsx
24
24
  var COLLAPSED_RESULT_LINES = 12;
25
25
  function LineSpans({ text, tokens, emphasis }) {
26
26
  const pieces = tokens ?? [{ content: text }];
27
- if (!emphasis || emphasis.length === 0) return /* @__PURE__ */ jsx(Fragment, { children: pieces.map((t, i) => /* @__PURE__ */ jsx("span", {
27
+ if (!emphasis || emphasis.length === 0) return /* @__PURE__ */ jsx(Fragment$1, { children: pieces.map((t, i) => /* @__PURE__ */ jsx("span", {
28
28
  style: t.color ? { color: t.color } : void 0,
29
29
  children: t.content
30
30
  }, i)) });
@@ -47,7 +47,7 @@ function LineSpans({ text, tokens, emphasis }) {
47
47
  }
48
48
  offset += t.content.length;
49
49
  }
50
- return /* @__PURE__ */ jsx(Fragment, { children: out });
50
+ return /* @__PURE__ */ jsx(Fragment$1, { children: out });
51
51
  }
52
52
  function DiffRows({ rows, lang }) {
53
53
  const [tokens, setTokens] = useState(null);
@@ -188,7 +188,7 @@ function ResultBody({ part }) {
188
188
  /** A status mark, which color alone tells apart, with its status in words for
189
189
  * a screen reader. */
190
190
  function StatusMark({ status, children }) {
191
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
191
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
192
192
  "aria-hidden": "true",
193
193
  className: "contents",
194
194
  children
@@ -232,7 +232,10 @@ function ToolStatusDot({ part }) {
232
232
  }
233
233
  /** A part's toggle row: its status mark and name, across the transcript's width. */
234
234
  var rowSummaryClasses = "min-h-6 w-full";
235
- function ToolCallBlock({ part }) {
235
+ /** A call's row: its status and signature, opening to its full arguments and
236
+ * result. `children` is a host's drawing of the call, in place of the
237
+ * one-line summary. */
238
+ function ToolCallBlock({ part, children }) {
236
239
  const { strings } = useChatConfig();
237
240
  const t = strings.agentTranscript;
238
241
  const [expanded, setExpanded] = useState(false);
@@ -259,7 +262,7 @@ function ToolCallBlock({ part }) {
259
262
  onOpenChange: setExpanded,
260
263
  disabled: isDiff,
261
264
  summaryClassName: rowSummaryClasses,
262
- summary: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ToolStatusDot, { part }), /* @__PURE__ */ jsxs("span", {
265
+ summary: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ToolStatusDot, { part }), /* @__PURE__ */ jsxs("span", {
263
266
  className: "font-mono text-[13px] leading-5 min-w-0 truncate",
264
267
  children: [/* @__PURE__ */ jsx("span", {
265
268
  className: "font-semibold",
@@ -279,7 +282,11 @@ function ToolCallBlock({ part }) {
279
282
  children: fullToolArgs(header.arg, part.args)
280
283
  }), /* @__PURE__ */ jsx(ResultBody, { part })]
281
284
  }),
282
- !isDiff && !expanded && part.status !== "waiting" && /* @__PURE__ */ jsx("div", {
285
+ children && /* @__PURE__ */ jsx("div", {
286
+ className: "ml-5 mt-1.5 min-w-0",
287
+ children
288
+ }),
289
+ !children && !isDiff && !expanded && part.status !== "waiting" && /* @__PURE__ */ jsx("div", {
283
290
  className: cx("ml-5 mt-0.5 truncate text-[13px]", part.status === "error" ? "text-(--theme-error-text)" : "theme-muted-text"),
284
291
  children: summary
285
292
  }),
@@ -313,14 +320,14 @@ function DecisionLine({ decision }) {
313
320
  className: "flex min-w-0 flex-wrap items-baseline gap-x-1",
314
321
  children: [
315
322
  /* @__PURE__ */ jsx("span", { children: decisionLabel(decision, strings.agentTranscript) }),
316
- decision.at && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
323
+ decision.at && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
317
324
  "aria-hidden": "true",
318
325
  children: "·"
319
326
  }), /* @__PURE__ */ jsx(RelativeTime, {
320
327
  value: decision.at,
321
328
  className: "shrink-0"
322
329
  })] }),
323
- decision.note && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
330
+ decision.note && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
324
331
  "aria-hidden": "true",
325
332
  children: "·"
326
333
  }), /* @__PURE__ */ jsx("span", {
@@ -355,7 +362,7 @@ function SubagentCard({ part }) {
355
362
  onOpenChange: setExpanded,
356
363
  disabled: !canExpand,
357
364
  summaryClassName: rowSummaryClasses,
358
- summary: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(StatusMark, {
365
+ summary: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StatusMark, {
359
366
  status: part.status === "running" ? t.running : part.status === "failed" ? t.failed : t.done,
360
367
  children: part.status === "running" ? /* @__PURE__ */ jsx("span", {
361
368
  className: "mt-[3px]",
@@ -430,7 +437,7 @@ function ConfirmApproval({ part, onAnswer }) {
430
437
  path: [t.allowPath, t.denyPath],
431
438
  call: [t.allowCall, t.denyCall]
432
439
  }[part.subject ?? "command"];
433
- return /* @__PURE__ */ jsxs(Fragment, { children: [
440
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
434
441
  part.command && /* @__PURE__ */ jsx("pre", {
435
442
  className: "overflow-x-auto rounded-md bg-(--theme-muted-panel-bg) p-2 font-mono text-xs whitespace-pre-wrap",
436
443
  children: part.command
@@ -518,7 +525,7 @@ function AskApproval({ part, onAnswer }) {
518
525
  kind: "ask",
519
526
  text
520
527
  });
521
- if (!onAnswer) return /* @__PURE__ */ jsxs(Fragment, { children: [
528
+ if (!onAnswer) return /* @__PURE__ */ jsxs(Fragment$1, { children: [
522
529
  part.question && /* @__PURE__ */ jsx("div", {
523
530
  className: "text-sm",
524
531
  children: part.question
@@ -535,7 +542,7 @@ function AskApproval({ part, onAnswer }) {
535
542
  children: t.approvalPending
536
543
  })
537
544
  ] });
538
- return /* @__PURE__ */ jsxs(Fragment, { children: [part.question && /* @__PURE__ */ jsx("div", {
545
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [part.question && /* @__PURE__ */ jsx("div", {
539
546
  className: "text-sm",
540
547
  children: part.question
541
548
  }), own === null ? /* @__PURE__ */ jsxs("div", {
@@ -610,7 +617,7 @@ function ApprovalBlock({ part, onApprovalAnswer }) {
610
617
  function PlanApproval({ part }) {
611
618
  const { strings } = useChatConfig();
612
619
  const t = strings.agentTranscript;
613
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
620
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
614
621
  className: "text-xs theme-muted-text",
615
622
  children: t.planPending
616
623
  }), part.plan && /* @__PURE__ */ jsx("div", {
@@ -735,6 +742,21 @@ function TextBlock({ part, isStreaming }) {
735
742
  }
736
743
  function PartDispatch(props) {
737
744
  const { slots } = useChatConfig();
745
+ const part = props.part;
746
+ const Tool = part.kind === "tool_call" ? slots.toolRenderers?.[part.name] : void 0;
747
+ if (Tool && part.kind === "tool_call") {
748
+ const approval = props.message.parts?.find((p) => p.kind === "approval" && p.id === part.id);
749
+ return /* @__PURE__ */ jsx(ToolCallBlock, {
750
+ part,
751
+ children: /* @__PURE__ */ jsx(Tool, {
752
+ part,
753
+ message: props.message,
754
+ ...approval ? { approval } : {},
755
+ ...props.isStreaming !== void 0 ? { isStreaming: props.isStreaming } : {},
756
+ ...props.onApprovalAnswer ? { onApprovalAnswer: props.onApprovalAnswer } : {}
757
+ })
758
+ });
759
+ }
738
760
  const Override = slots.partRenderers?.[props.part.kind];
739
761
  if (Override) return /* @__PURE__ */ jsx(Override, { ...props });
740
762
  return /* @__PURE__ */ jsx(BuiltinPart, {
@@ -783,7 +805,7 @@ function mergeReasoning(parts) {
783
805
  ...durationMs > 0 ? { durationMs } : {}
784
806
  };
785
807
  }
786
- function buildRenderItems(parts) {
808
+ function buildRenderItems(parts, hostDrawn = () => false) {
787
809
  const items = [];
788
810
  let run = [];
789
811
  const emitThoughts = (members) => {
@@ -825,9 +847,11 @@ function buildRenderItems(parts) {
825
847
  run = [];
826
848
  };
827
849
  const decided = new Set(parts.flatMap((p) => p.kind === "tool_call" && p.decision ? [p.id] : []));
850
+ const drawnByHost = new Set(parts.flatMap((p) => p.kind === "tool_call" && hostDrawn(p.name) ? [p.id] : []));
828
851
  parts.forEach((part, index) => {
829
852
  if (part.kind === "approval" && part.resolved && decided.has(part.id)) return;
830
- if (part.kind === "reasoning" || part.kind === "tool_call" && part.status === "ok" && !part.decision && isGroupableTool(part.name)) {
853
+ if (part.kind === "approval" && drawnByHost.has(part.id)) return;
854
+ if (part.kind === "reasoning" || part.kind === "tool_call" && part.status === "ok" && !part.decision && !drawnByHost.has(part.id) && isGroupableTool(part.name)) {
831
855
  run.push({
832
856
  part,
833
857
  index
@@ -853,7 +877,7 @@ function RollupGroup({ members, message }) {
853
877
  children: /* @__PURE__ */ jsx(Disclosure, {
854
878
  keepMounted: true,
855
879
  summaryClassName: rowSummaryClasses,
856
- summary: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
880
+ summary: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
857
881
  className: "text-(--theme-success) leading-none",
858
882
  "aria-hidden": "true",
859
883
  children: "●"
@@ -871,7 +895,9 @@ function RollupGroup({ members, message }) {
871
895
  }
872
896
  function AgentMessageParts({ message, isStreaming, onApprovalAnswer }) {
873
897
  const parts = message.parts ?? [];
874
- const items = useMemo(() => buildRenderItems(parts), [parts]);
898
+ const { slots } = useChatConfig();
899
+ const toolRenderers = slots.toolRenderers;
900
+ const items = useMemo(() => buildRenderItems(parts, (name) => !!toolRenderers?.[name]), [parts, toolRenderers]);
875
901
  const lastIndex = parts.length - 1;
876
902
  return /* @__PURE__ */ jsx("div", {
877
903
  className: "w-full",
@@ -1,13 +1,13 @@
1
+ import { useContextMenu } from "../../components/ContextMenu.js";
1
2
  import { toast } from "../../components/Toast.js";
2
3
  import { useStrings } from "../../components/Provider.js";
3
- import { useContextMenu } from "../../components/ContextMenu.js";
4
4
  import { useChatConfig } from "../core/config.js";
5
5
  import { useChat } from "../core/ChatProvider.js";
6
6
  import { useRowDialogs, useSessionMenu } from "../ui/sidebar.js";
7
7
  import { conversationToMarkdown, downloadText, exportFilename } from "../core/exportConversation.js";
8
8
  import ShareDialog from "./ShareDialog.js";
9
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
9
  import { useState } from "react";
10
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { DateTime } from "luxon";
12
12
  //#region src/ai/components/conversationActions.tsx
13
13
  /** Conversations by how long ago they last changed, the time each row shows,
@@ -73,7 +73,7 @@ function useConversationActions() {
73
73
  return {
74
74
  menuItems,
75
75
  openMenu,
76
- overlays: /* @__PURE__ */ jsxs(Fragment, { children: [
76
+ overlays: /* @__PURE__ */ jsxs(Fragment$1, { children: [
77
77
  contextMenu,
78
78
  dialogs,
79
79
  sharing && /* @__PURE__ */ jsx(ShareDialog, {
@@ -6,8 +6,8 @@ import { ChatConfigProvider, resolveChatConfig } from "./config.js";
6
6
  import { providerIssueFor } from "./providerIssues.js";
7
7
  import { ReportSidebarPresentationContext, useControllable, useOwnSidebar } from "./sidebarState.js";
8
8
  import { useSSEStream } from "./useSSEStream.js";
9
- import { jsx } from "react/jsx-runtime";
10
9
  import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
11
  import { DateTime } from "luxon";
12
12
  //#region src/ai/core/ChatProvider.tsx
13
13
  function generateTitleFromMessage(content) {
@@ -637,6 +637,14 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
637
637
  at: DateTime.now().toUTC().toISO()
638
638
  }
639
639
  });
640
+ const instead = answer.allowed ? answer.instead : void 0;
641
+ if (instead) {
642
+ pausedParts = pausedParts.map((p) => p.kind === "tool_call" && p.id === approvalId ? {
643
+ ...p,
644
+ name: instead
645
+ } : p);
646
+ updatePaused({ parts: pausedParts });
647
+ }
640
648
  streamingToConversationRef.current = targetConversationId;
641
649
  startStreaming(targetConversationId);
642
650
  try {
@@ -652,7 +660,8 @@ function ChatProvider({ adapter, currentUser, navigation, activeConversationId =
652
660
  messageId: paused.id,
653
661
  toolCallId: approvalId,
654
662
  allowed: answer.allowed,
655
- ...answer.denyMessage ? { feedback: answer.denyMessage } : {}
663
+ ...answer.denyMessage ? { feedback: answer.denyMessage } : {},
664
+ ...instead ? { tool: instead } : {}
656
665
  }
657
666
  }, paused.id, (message) => updatePaused({ error: message }), (delta) => {
658
667
  if (delta.type !== "tool_end" || delta.id !== approvalId) return false;
@@ -1,13 +1,21 @@
1
1
  import { type ComponentType, type MouseEventHandler, type ReactNode } from 'react';
2
2
  import type { Components } from 'streamdown';
3
3
  import { type ChatStrings } from '../strings.js';
4
- import type { ApprovalAnswerValue, ChatLinkTarget, ChatMessage, CspKind, MessagePart, MessagePartKind } from '../types.js';
4
+ import type { ApprovalAnswerValue, ApprovalPart, ChatLinkTarget, ChatMessage, CspKind, MessagePart, MessagePartKind, ToolCallPart } from '../types.js';
5
5
  export interface PartRendererProps {
6
6
  part: MessagePart;
7
7
  message: ChatMessage;
8
8
  isStreaming?: boolean;
9
9
  onApprovalAnswer?: (id: string, answer: ApprovalAnswerValue) => void;
10
10
  }
11
+ export interface ToolRendererProps {
12
+ part: ToolCallPart;
13
+ approval?: ApprovalPart;
14
+ message: ChatMessage;
15
+ isStreaming?: boolean;
16
+ /** Absent when the reader may not answer, such as a call someone else asked for. */
17
+ onApprovalAnswer?: (id: string, answer: ApprovalAnswerValue) => void;
18
+ }
11
19
  export interface ChatLinkProps {
12
20
  target: ChatLinkTarget;
13
21
  className?: string;
@@ -27,6 +35,7 @@ export interface ChatUIConfig {
27
35
  composerUsage?: ReactNode;
28
36
  providerIcon?: (cspKind: CspKind, className?: string) => ReactNode;
29
37
  partRenderers?: Partial<Record<MessagePartKind, ComponentType<PartRendererProps>>>;
38
+ toolRenderers?: Record<string, ComponentType<ToolRendererProps>>;
30
39
  };
31
40
  strings?: {
32
41
  [S in keyof ChatStrings]?: Partial<ChatStrings[S]>;
@@ -1,7 +1,7 @@
1
1
  import { AppLink } from "../../components/AppLink.js";
2
2
  import { defaultChatStrings } from "../strings.js";
3
- import { jsx } from "react/jsx-runtime";
4
3
  import { createContext, useContext } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/ai/core/config.tsx
6
6
  function hrefFor(target) {
7
7
  switch (target.kind) {
@@ -27,7 +27,7 @@ export { type SlashCommandOption, type SlashMenuConfig, slashMatches, } from './
27
27
  export type { ComposerPastes, PasteUploadResult, } from './components/usePasteCards.js';
28
28
  export { ChatProvider, type ChatProviderProps, type ChatStream, useChat, useChatStream, } from './core/ChatProvider.js';
29
29
  export { type ChatAction, type ChatState, chatReducer, initialState, } from './core/chatReducer.js';
30
- export type { PartRendererProps } from './core/config.js';
30
+ export type { PartRendererProps, ToolRendererProps } from './core/config.js';
31
31
  export { type ChatLinkProps, type ChatUIConfig, resolveChatConfig, useChatConfig, } from './core/config.js';
32
32
  export { FOCUS_SIDEBAR_SEARCH_EVENT } from './core/events.js';
33
33
  export { getGreeting } from './core/greeting.js';
@@ -91,6 +91,8 @@ export interface ChatStrings {
91
91
  stop: string;
92
92
  /** The status words an agent's working line picks from, one per turn. */
93
93
  words: readonly string[];
94
+ /** The working line while a call waits for the reader to allow it. */
95
+ waitingForAnswer: string;
94
96
  };
95
97
  emptyState: {
96
98
  greeting: string | null;
@@ -116,7 +116,8 @@ var defaultChatStrings = {
116
116
  "Crunching",
117
117
  "Forging",
118
118
  "Cooking"
119
- ]
119
+ ],
120
+ waitingForAnswer: "Waiting for your answer"
120
121
  },
121
122
  emptyState: {
122
123
  greeting: null,
@@ -100,6 +100,9 @@ export type ApprovalAnswerValue = {
100
100
  allowed: boolean;
101
101
  allowDir?: boolean;
102
102
  denyMessage?: string;
103
+ /** A sibling tool to run in place of the one asked for, with the same
104
+ * arguments, such as destroying a cluster the model asked to stop. */
105
+ instead?: string;
103
106
  } | {
104
107
  kind: 'ask';
105
108
  text: string;
@@ -1,12 +1,12 @@
1
1
  import { cx } from "../../cx.js";
2
- import { positionKeys } from "../../components/keys.js";
3
2
  import { usePersistedState } from "../../components/Provider.js";
3
+ import { positionKeys } from "../../components/keys.js";
4
4
  import { LoadingRegion, Skeleton } from "../../components/Skeleton.js";
5
5
  import { useSplitter } from "../../components/splitter.js";
6
6
  import { Drawer } from "../../components/Drawer.js";
7
7
  import { SidebarGroupHeading, SidebarPanel, SidebarToggle } from "./sidebar.js";
8
+ import { Fragment, useEffect, useRef } from "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
- import { Fragment as Fragment$1, useEffect, useRef } from "react";
10
10
  /** A conversation list's drawer on a layout too narrow to keep it beside the
11
11
  * content: it covers the chat's own positioned container, not the window, and
12
12
  * stays mounted so the list keeps its scroll and search between openings. */
@@ -101,7 +101,7 @@ function ConversationSidebar({ label, collapsed: collapsedProp, onToggle, toggle
101
101
  children: group.label
102
102
  }), /* @__PURE__ */ jsx("ul", {
103
103
  className: "space-y-0.5",
104
- children: group.items.map((item) => /* @__PURE__ */ jsx(Fragment$1, { children: renderRow(item) }, getKey(item)))
104
+ children: group.items.map((item) => /* @__PURE__ */ jsx(Fragment, { children: renderRow(item) }, getKey(item)))
105
105
  })]
106
106
  }, group.key))
107
107
  }),
@@ -1,17 +1,17 @@
1
1
  import { cx } from "../../cx.js";
2
+ import { EmptyState } from "../../components/EmptyState.js";
2
3
  import { DownloadIcon, RenameIcon, ShareIcon, SidebarIcon, TrashIcon } from "../../icons.js";
3
4
  import { Tooltip } from "../../components/Tooltip.js";
4
5
  import { useStrings } from "../../components/Provider.js";
5
6
  import { AppLink, isPlainClick } from "../../components/AppLink.js";
6
- import { EmptyState } from "../../components/EmptyState.js";
7
7
  import { menuDivider } from "../../components/MenuEntries.js";
8
8
  import { IconButton } from "../../components/IconButton.js";
9
9
  import { fieldBox } from "../../components/fieldBox.js";
10
10
  import { focusOnMount } from "../../components/focus.js";
11
11
  import { ConfirmModal } from "../../components/ConfirmModal.js";
12
12
  import { MoreButton, rowContextMenuProps, useRowMenuActive } from "../../list/rowMenu.js";
13
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
13
  import { useState } from "react";
14
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
15
  //#region src/ai/ui/sidebar.tsx
16
16
  var SIDEBAR_RAIL_WIDTH_PX = 48;
17
17
  var HIGHLIGHT_SELECTED = "bg-[color-mix(in_oklab,var(--theme-accent)_12%,transparent)]";
@@ -214,7 +214,7 @@ function useRowDialogs({ strings, nameOf, onDelete, onRename }) {
214
214
  setName(nameOf(item));
215
215
  setToRename(item);
216
216
  },
217
- dialogs: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ConfirmModal, {
217
+ dialogs: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ConfirmModal, {
218
218
  open: toDelete !== null,
219
219
  onClose: () => setToDelete(null),
220
220
  align: "center",