@docyrus/ui-pro-ai-assistant 0.3.3 → 0.3.5

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 CHANGED
@@ -139,6 +139,7 @@ import type {
139
139
  AssistantConfig,
140
140
  AssistantUser,
141
141
  AgentTriggerWidgetProps,
142
+ InitialFeatureFlags,
142
143
  PromptFeatureFlags,
143
144
  Project,
144
145
  Work,
@@ -270,7 +271,7 @@ The main chat interface component.
270
271
  |------|------|---------|-------------|
271
272
  | `initialPrompt` | `string` | — | When provided, the assistant auto-sends this message on mount. Useful when launching the assistant from an agent trigger widget or deep link |
272
273
  | `initialModelId` | `string` | — | Model ID to pre-select when auto-sending the initial prompt |
273
- | `initialFeatures` | `{ webSearch?, thinking?, deepResearch?, documentSearch?, workCanvas?, files? }` | — | Feature flags to enable when auto-sending the initial prompt |
274
+ | `initialFeatures` | `InitialFeatureFlags` | — | Feature flags to enable when auto-sending the initial prompt |
274
275
  | `initialFiles` | `File[]` | — | Files to attach when auto-sending the initial prompt |
275
276
 
276
277
  ---
@@ -312,7 +313,20 @@ interface PromptFeatureFlags {
312
313
  deepResearch: boolean;
313
314
  documentSearch: boolean;
314
315
  workCanvas: boolean;
315
- files: boolean;
316
+ }
317
+ ```
318
+
319
+ #### `InitialFeatureFlags`
320
+
321
+ Used by `DocyAssistant.initialFeatures` — all fields are optional since you only need to set the ones you want enabled:
322
+
323
+ ```ts
324
+ interface InitialFeatureFlags {
325
+ webSearch?: boolean;
326
+ thinking?: boolean;
327
+ deepResearch?: boolean;
328
+ documentSearch?: boolean;
329
+ workCanvas?: boolean;
316
330
  }
317
331
  ```
318
332
 
@@ -6,7 +6,6 @@ export interface PromptFeatureFlags {
6
6
  deepResearch: boolean;
7
7
  documentSearch: boolean;
8
8
  workCanvas: boolean;
9
- files: boolean;
10
9
  }
11
10
  export interface AgentTriggerPromptProps {
12
11
  agentId: string | null;
@@ -1,4 +1,5 @@
1
1
  import { type ChangeEvent, type FC, type FormEvent } from 'react';
2
+ import { type InitialFeatureFlags } from '../types';
2
3
  interface SubmitOptions {
3
4
  modelId?: string;
4
5
  supportMultipleModels?: boolean;
@@ -45,13 +46,7 @@ interface AIInputAreaProps {
45
46
  hasMessages?: boolean;
46
47
  tenantAiProjectId?: string;
47
48
  initialModelId?: string;
48
- initialFeatures?: {
49
- webSearch?: boolean;
50
- thinking?: boolean;
51
- deepResearch?: boolean;
52
- documentSearch?: boolean;
53
- workCanvas?: boolean;
54
- };
49
+ initialFeatures?: InitialFeatureFlags;
55
50
  }
56
51
  export declare const AIInputArea: FC<AIInputAreaProps>;
57
52
  export {};
package/dist/index.d.ts CHANGED
@@ -3,4 +3,4 @@ export { type AssistantConfig, AssistantProvider, type AssistantUser, useAssista
3
3
  export { AssistantI18nProvider, useAssistantTranslation } from './i18n';
4
4
  export { AgentTriggerWidget, type AgentTriggerWidgetProps } from './components/agent-trigger-widget';
5
5
  export { type PromptFeatureFlags } from './components/agent-trigger-widget/agent-trigger-prompt';
6
- export type { Project, Work, WorkTypes } from './types';
6
+ export type { InitialFeatureFlags, Project, Work, WorkTypes } from './types';
package/dist/index.js CHANGED
@@ -22763,14 +22763,14 @@ var AssistantView = ({ ref, ...props }) => {
22763
22763
  ] })
22764
22764
  ] }),
22765
22765
  /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-row min-h-0 overflow-hidden relative", children: [
22766
- !isSidebarOpen && /* @__PURE__ */ jsxs("div", { className: "absolute top-2 left-2 z-40 flex flex-col gap-1", children: [
22766
+ !isSidebarOpen && /* @__PURE__ */ jsxs("div", { className: "absolute top-2 left-2 z-40 flex flex-col gap-1 rounded-md bg-background/80 backdrop-blur-sm p-0.5", children: [
22767
22767
  enableSidebar && onToggleSidebar && /* @__PURE__ */ jsx(
22768
22768
  Button,
22769
22769
  {
22770
22770
  variant: "ghost",
22771
22771
  size: "icon",
22772
22772
  onClick: onToggleSidebar,
22773
- className: "h-8 w-8 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-md shadow-sm",
22773
+ className: "h-8 w-8 text-foreground hover:bg-accent hover:text-accent-foreground rounded-md",
22774
22774
  title: t("tabs.sessions"),
22775
22775
  children: /* @__PURE__ */ jsx(PanelLeft, { className: "w-4 h-4" })
22776
22776
  }
@@ -22782,7 +22782,7 @@ var AssistantView = ({ ref, ...props }) => {
22782
22782
  size: "icon",
22783
22783
  onClick: () => onTabChange(activeTab === 4 ? 0 : 4),
22784
22784
  className: cn(
22785
- "h-8 w-8 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-md shadow-sm",
22785
+ "h-8 w-8 text-foreground hover:bg-accent hover:text-accent-foreground rounded-md",
22786
22786
  activeTab === 4 && "bg-background text-foreground shadow"
22787
22787
  ),
22788
22788
  title: t("tabs.memories"),
@@ -22795,7 +22795,7 @@ var AssistantView = ({ ref, ...props }) => {
22795
22795
  variant: "ghost",
22796
22796
  size: "icon",
22797
22797
  onClick: onNewChat,
22798
- className: "h-8 w-8 text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-md shadow-sm",
22798
+ className: "h-8 w-8 text-foreground hover:bg-accent hover:text-accent-foreground rounded-md",
22799
22799
  title: t("buttons.start_new_thread"),
22800
22800
  children: /* @__PURE__ */ jsx(Edit, { className: "w-4 h-4" })
22801
22801
  }
@@ -23257,7 +23257,7 @@ function MemoryDialog({
23257
23257
  ] })
23258
23258
  ] }) });
23259
23259
  }
23260
- var MemoriesPanel = ({ t }) => {
23260
+ var MemoriesPanel = ({ t, sidebarOffset }) => {
23261
23261
  const apiClient = useApiClient();
23262
23262
  const [memories, setMemories] = useState([]);
23263
23263
  const [loading, setLoading] = useState(false);
@@ -23319,7 +23319,7 @@ var MemoriesPanel = ({ t }) => {
23319
23319
  return m.title.toLowerCase().includes(q) || m.content.toLowerCase().includes(q);
23320
23320
  });
23321
23321
  return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-y-auto p-6", children: [
23322
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-6", children: [
23322
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between mb-6", sidebarOffset && "ml-6"), children: [
23323
23323
  /* @__PURE__ */ jsx("div", { className: "flex flex-col min-w-0", children: /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold ps-2", children: t("tabs.memories") }) }),
23324
23324
  /* @__PURE__ */ jsxs(
23325
23325
  Button,
@@ -23433,12 +23433,13 @@ var AssistantProjectDetailView = ({
23433
23433
  enableVoice,
23434
23434
  isRecording,
23435
23435
  recognition,
23436
- onMicrophoneClick
23436
+ onMicrophoneClick,
23437
+ sidebarOffset
23437
23438
  }) => {
23438
23439
  const { t } = useAssistantTranslation();
23439
23440
  const [activeTab, setActiveTab] = useState("sessions");
23440
23441
  return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col px-6 mt-2 overflow-y-auto", children: [
23441
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
23442
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 mb-2", sidebarOffset && "ml-6"), children: [
23442
23443
  /* @__PURE__ */ jsx(
23443
23444
  Button,
23444
23445
  {
@@ -23771,10 +23772,11 @@ var SessionsListView = ({
23771
23772
  onSessionClick,
23772
23773
  onEditSession,
23773
23774
  onDeleteSession,
23774
- t
23775
+ t,
23776
+ sidebarOffset
23775
23777
  }) => {
23776
23778
  return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-y-auto p-6", children: [
23777
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-6", children: [
23779
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between mb-6", sidebarOffset && "ml-6"), children: [
23778
23780
  /* @__PURE__ */ jsx("div", { className: "flex flex-col min-w-0", children: /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold ps-2", children: t("tabs.sessions") }) }),
23779
23781
  /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onNewSession, className: "shrink-0", children: [
23780
23782
  /* @__PURE__ */ jsx(Plus, { className: "w-4 h-4" }),
@@ -25075,7 +25077,6 @@ var DocyAssistant = ({
25075
25077
  initialOptions.supportDeepResearch = initialFeatures.deepResearch;
25076
25078
  initialOptions.supportDocumentSearch = initialFeatures.documentSearch;
25077
25079
  initialOptions.supportWorkCanvas = initialFeatures.workCanvas;
25078
- initialOptions.supportFiles = initialFeatures.files;
25079
25080
  }
25080
25081
  if (initialFiles && initialFiles.length > 0) {
25081
25082
  const fileData = [];
@@ -25369,7 +25370,8 @@ var DocyAssistant = ({
25369
25370
  sessionActions.selectSession(session);
25370
25371
  sessionActions.setDeleteDialogOpen(true);
25371
25372
  },
25372
- t
25373
+ t,
25374
+ sidebarOffset: !uiState.isSidebarOpen && enableSidebar
25373
25375
  }
25374
25376
  ),
25375
25377
  renderProjectsView: () => projectState.view === "create" ? /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col p-6", children: [
@@ -25479,7 +25481,8 @@ var DocyAssistant = ({
25479
25481
  enableVoice,
25480
25482
  isRecording,
25481
25483
  recognition,
25482
- onMicrophoneClick: handleMicrophoneClick
25484
+ onMicrophoneClick: handleMicrophoneClick,
25485
+ sidebarOffset: !uiState.isSidebarOpen && enableSidebar
25483
25486
  }
25484
25487
  ) : /* @__PURE__ */ jsx(
25485
25488
  AssistantProjectsPanel,
@@ -25506,7 +25509,7 @@ var DocyAssistant = ({
25506
25509
  t
25507
25510
  }
25508
25511
  ),
25509
- renderMemoriesView: () => /* @__PURE__ */ jsx(MemoriesPanel, { t }),
25512
+ renderMemoriesView: () => /* @__PURE__ */ jsx(MemoriesPanel, { t, sidebarOffset: !uiState.isSidebarOpen && enableSidebar }),
25510
25513
  renderWorksView: () => worksState.detailViewWork ? /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col overflow-y-auto", children: /* @__PURE__ */ jsx(
25511
25514
  AssistantWorkDetailView,
25512
25515
  {
@@ -25515,7 +25518,7 @@ var DocyAssistant = ({
25515
25518
  onBack: () => worksActions.setDetailViewWork(null)
25516
25519
  }
25517
25520
  ) }) : /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-y-auto p-6", children: [
25518
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-6", children: [
25521
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between mb-6", !uiState.isSidebarOpen && enableSidebar && "ml-6"), children: [
25519
25522
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
25520
25523
  /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold ps-2", children: t("tabs.works") }),
25521
25524
  /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground ps-2", children: t("descriptions.manage_works") })
@@ -25767,9 +25770,9 @@ function computeVisibleSlots(agents, index) {
25767
25770
  }
25768
25771
  var SLOT_OUTER_CLASS = {
25769
25772
  0: "z-0 mx-2",
25770
- 1: "z-5 mx-4",
25773
+ 1: "z-[5] mx-4",
25771
25774
  2: "z-10 mx-6",
25772
- 3: "z-5 mx-4",
25775
+ 3: "z-[5] mx-4",
25773
25776
  4: "z-0 mx-2"
25774
25777
  };
25775
25778
  var SLOT_CIRCLE_CLASS = {
@@ -25917,12 +25920,6 @@ var CAPABILITY_TOGGLES = [
25917
25920
  capKey: "supportWorkCanvas",
25918
25921
  icon: PenTool,
25919
25922
  labelKey: "tools.work_canvas"
25920
- },
25921
- {
25922
- key: "files",
25923
- capKey: "supportFiles",
25924
- icon: FileUp,
25925
- labelKey: "tools.file_upload"
25926
25923
  }
25927
25924
  ];
25928
25925
  var ACCEPTED_FILE_TYPES = ".pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.json,.xml,.png,.jpg,.jpeg,.gif,.webp";
@@ -25958,13 +25955,20 @@ function ToggleSwitch({
25958
25955
  function useClickOutside(ref, open, onClose) {
25959
25956
  useEffect(() => {
25960
25957
  if (!open) return;
25961
- const handler = (e) => {
25958
+ const handleClick = (e) => {
25962
25959
  if (ref.current && !ref.current.contains(e.target)) {
25963
25960
  onClose();
25964
25961
  }
25965
25962
  };
25966
- document.addEventListener("mousedown", handler);
25967
- return () => document.removeEventListener("mousedown", handler);
25963
+ const handleEscape = (e) => {
25964
+ if (e.key === "Escape") onClose();
25965
+ };
25966
+ document.addEventListener("mousedown", handleClick);
25967
+ document.addEventListener("keydown", handleEscape);
25968
+ return () => {
25969
+ document.removeEventListener("mousedown", handleClick);
25970
+ document.removeEventListener("keydown", handleEscape);
25971
+ };
25968
25972
  }, [ref, open, onClose]);
25969
25973
  }
25970
25974
  function AgentTriggerPrompt({
@@ -25987,8 +25991,7 @@ function AgentTriggerPrompt({
25987
25991
  thinking: false,
25988
25992
  deepResearch: false,
25989
25993
  documentSearch: false,
25990
- workCanvas: false,
25991
- files: false
25994
+ workCanvas: false
25992
25995
  });
25993
25996
  const [settingsOpen, setSettingsOpen] = useState(false);
25994
25997
  const [modelDropdownOpen, setModelDropdownOpen] = useState(false);
@@ -26010,6 +26013,11 @@ function AgentTriggerPrompt({
26010
26013
  useClickOutside(settingsRef, settingsOpen, () => setSettingsOpen(false));
26011
26014
  useClickOutside(modelRef, modelDropdownOpen, () => setModelDropdownOpen(false));
26012
26015
  useClickOutside(reasoningRef, reasoningDropdownOpen, () => setReasoningDropdownOpen(false));
26016
+ useEffect(() => () => {
26017
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state === "recording") {
26018
+ mediaRecorderRef.current.stop();
26019
+ }
26020
+ }, []);
26013
26021
  useEffect(() => {
26014
26022
  if (models.length > 0 && !models.find((m) => m.id === selectedModel?.id)) {
26015
26023
  setSelectedModel(models[0]);
@@ -26414,7 +26422,8 @@ function AgentTriggerWidget({
26414
26422
  } = useAgentsData(agentIds);
26415
26423
  const [carouselIndex, setCarouselIndex] = useState(0);
26416
26424
  const containerRef = useRef(null);
26417
- const currentAgent = agents[carouselIndex] ?? null;
26425
+ const safeIndex = agents.length > 0 ? Math.min(carouselIndex, agents.length - 1) : 0;
26426
+ const currentAgent = agents[safeIndex] ?? null;
26418
26427
  const navigateCarousel = useCallback(
26419
26428
  (direction) => {
26420
26429
  if (agents.length <= 1) return;
@@ -26431,10 +26440,7 @@ function AgentTriggerWidget({
26431
26440
  },
26432
26441
  [currentAgent, onSubmit]
26433
26442
  );
26434
- const welcomeText = useMemo(() => {
26435
- if (!currentAgent?.welcomeMessage) return "";
26436
- return currentAgent.welcomeMessage;
26437
- }, [currentAgent?.welcomeMessage]);
26443
+ const welcomeText = currentAgent?.welcomeMessage ?? "";
26438
26444
  if (isLoading) {
26439
26445
  return /* @__PURE__ */ jsxs(
26440
26446
  "div",
@@ -26501,7 +26507,7 @@ function AgentTriggerWidget({
26501
26507
  AgentCarousel,
26502
26508
  {
26503
26509
  agents,
26504
- selectedIndex: carouselIndex,
26510
+ selectedIndex: safeIndex,
26505
26511
  onSelect: setCarouselIndex,
26506
26512
  onNavigate: navigateCarousel
26507
26513
  }