@docyrus/ui-pro-ai-assistant 0.5.3 → 0.5.4

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.
@@ -55,7 +55,12 @@ interface GenerativeUIToolProps {
55
55
  text: string;
56
56
  }) => void;
57
57
  workId?: string;
58
- agent?: Record<string, any>;
58
+ /**
59
+ * Combined list of subagents reachable from this orchestrator (direct
60
+ * children + connected subagents). Used to resolve the `subagent` record
61
+ * for `call*Agent` tool calls by matching the agentId on the result.
62
+ */
63
+ subagents?: Array<Record<string, any>>;
59
64
  }
60
- export declare function GenerativeUITool({ part, toolName, onToolAction, openCanvasView, onUseWorkResult, onSendSpreadsheetCommands, onForwardToAgent, onInsertText, onReplaceText, workId, agent }: GenerativeUIToolProps): import("react/jsx-runtime").JSX.Element | null;
65
+ export declare function GenerativeUITool({ part, toolName, onToolAction, openCanvasView, onUseWorkResult, onSendSpreadsheetCommands, onForwardToAgent, onInsertText, onReplaceText, workId, subagents }: GenerativeUIToolProps): import("react/jsx-runtime").JSX.Element | null;
61
66
  export {};
@@ -2,13 +2,13 @@ interface SubagentToolProps {
2
2
  toolState: string;
3
3
  input?: Record<string, any>;
4
4
  status?: string;
5
- text?: string;
6
- icon?: string;
7
- skillName?: string;
8
- agentName?: string;
9
5
  step?: Record<string, any>;
10
6
  result?: Record<string, any>;
11
- agent?: Record<string, any>;
7
+ /**
8
+ * Resolved subagent record from `deployment.agent.{agents,connectedAgents}`.
9
+ * Carries name / description / avatar / steps for rendering.
10
+ */
11
+ subagent?: Record<string, any> | null;
12
12
  openCanvasView?: (options: {
13
13
  type: string;
14
14
  id: string;
@@ -16,7 +16,8 @@ interface SubagentToolProps {
16
16
  title?: string;
17
17
  description?: string;
18
18
  contentJson?: Record<string, any> | null;
19
+ workId?: string;
19
20
  }) => void;
20
21
  }
21
- export declare function SubagentTool({ toolState, input, status, skillName, agentName, step, result, agent, openCanvasView }: SubagentToolProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function SubagentTool({ toolState, input, status, step, result, subagent, openCanvasView }: SubagentToolProps): import("react/jsx-runtime").JSX.Element;
22
23
  export {};
@@ -13,6 +13,13 @@ interface UseAssistantApiReturn {
13
13
  welcomeMessage?: string;
14
14
  } | null;
15
15
  isLoadingAgentDetails: boolean;
16
+ /**
17
+ * Combined list of subagents reachable from this orchestrator (direct
18
+ * children + connected subagents), normalized so each has `id` and `name`.
19
+ * Used by the SubagentTool to render avatars / names / step templates for
20
+ * `call*Agent` tool calls.
21
+ */
22
+ subagents: Array<Record<string, any>>;
16
23
  fetchThreads: () => Promise<AssistantSession[]>;
17
24
  fetchProjectThreads: (projectId: string) => Promise<AssistantSession[]>;
18
25
  loadThreadMessages: (threadId: string) => Promise<any[]>;
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { Input } from '@docyrus/ui-pro-shared/components/input';
9
9
  import { Tabs as Tabs$1, TabsList as TabsList$1, TabsTrigger as TabsTrigger$1, TabsContent as TabsContent$1 } from '@docyrus/ui-pro-shared/components/tabs';
10
10
  import { cn } from '@docyrus/ui-pro-shared/lib/utils';
11
11
  import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls } from 'ai';
12
- import { Pencil, PilcrowIcon, Heading1Icon, Heading2Icon, Heading3Icon, SquareIcon, ListIcon, ListOrderedIcon, ChevronDownIcon, Code2Icon, QuoteIcon, LightbulbIcon, Columns3Icon, GripVertical, FileUpIcon, TableIcon, ImageIcon, FilmIcon, AudioLinesIcon, TableOfContentsIcon, RadicalIcon, RectangleVerticalIcon, CalendarIcon, PlusIcon, FileCodeIcon, MinusIcon, ChevronRightIcon, ListTree, PenToolIcon, Link2Icon, Check, X, Copy, FilesIcon, Link, Text, ExternalLink, Unlink, Bold, Italic, Underline, Strikethrough, Code2, MoreHorizontal, ArrowLeftIcon, ArrowRightIcon, Minus, Plus, CircleArrowDown, Minimize2, Trash2, FileUp, CheckCircle2, FileText, Loader2, CornerDownLeftIcon, PencilLineIcon, MessageSquareTextIcon, MessagesSquareIcon, ArrowUpIcon, CheckIcon, CaptionsIcon, ZoomInIcon, CircleArrowDownIcon, MoveUpRightIcon, MoreHorizontalIcon, Eye, PlusCircle, HelpCircle, Maximize2, Download, FileSpreadsheet, ChevronDown, ChevronLeft, ChevronRight, CheckCircle, XCircle, Search, Globe, FolderOpen, User, ArrowRight, MapPin, CalendarClock, List, RefreshCw, FilePlus, XIcon, CornerUpLeftIcon, AlbumIcon, FeatherIcon, ListMinusIcon, ListPlusIcon, ListEnd, Wand, LanguagesIcon, BadgeHelpIcon, PenLineIcon, SearchIcon, MusicIcon, CompassIcon, SmileIcon, LeafIcon, ClockIcon, AppleIcon, FlagIcon, StarIcon, DeleteIcon, AlignLeft, AlignCenter, AlignRight, RotateCcw, AlertTriangle, AlertCircle, ArrowUpDown, ArrowDownToLine, PenLine, PencilIcon, TrashIcon, FileIcon, Star, ChevronsUpDown, FolderIcon, MessageSquare, Hash, Table, CheckSquare, Calendar as Calendar$1, Clock, Phone, Mail, Send, RefreshCcw, Undo2, ChevronsUpDownIcon, ChevronsRight, ChevronsLeft, CalendarDays, RefreshCwIcon, PaintRoller, MessageSquareText, ArrowLeft, Users, Bot, Brain, Lightbulb, BookOpen, PenTool, SlidersHorizontal, Wand2, Mic, Code, Trash, Edit, Share, FolderInput, Archive, Building2, ShieldCheck, Sparkles, PanelLeft, NotebookText, CirclePlus, MoreVertical, FileSearch, Microscope, Ruler, AudioLines, BrainCircuit, File as File$1, Plug, Inbox, Menu, LayoutDashboard, Table2, WandSparklesIcon, ArrowUpToLineIcon, BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, HighlighterIcon, Undo2Icon, Redo2Icon, ArrowDownToLineIcon, AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifyIcon, ListOrdered, ListTodoIcon, ListCollapseIcon, Grid3x3Icon, Combine, Ungroup, ArrowUp, ArrowDown, Trash2Icon, LinkIcon, WrapText, OutdentIcon, IndentIcon, EyeIcon, PenIcon } from 'lucide-react';
12
+ import { Pencil, PilcrowIcon, Heading1Icon, Heading2Icon, Heading3Icon, SquareIcon, ListIcon, ListOrderedIcon, ChevronDownIcon, Code2Icon, QuoteIcon, LightbulbIcon, Columns3Icon, GripVertical, FileUpIcon, TableIcon, ImageIcon, FilmIcon, AudioLinesIcon, TableOfContentsIcon, RadicalIcon, RectangleVerticalIcon, CalendarIcon, PlusIcon, FileCodeIcon, MinusIcon, ChevronRightIcon, ListTree, PenToolIcon, Link2Icon, Check, X, Copy, FilesIcon, Link, Text, ExternalLink, Unlink, Bold, Italic, Underline, Strikethrough, Code2, MoreHorizontal, ArrowLeftIcon, ArrowRightIcon, Minus, Plus, CircleArrowDown, Minimize2, Trash2, FileUp, CheckCircle2, FileText, Loader2, CornerDownLeftIcon, PencilLineIcon, MessageSquareTextIcon, MessagesSquareIcon, ArrowUpIcon, CheckIcon, CaptionsIcon, ZoomInIcon, CircleArrowDownIcon, MoveUpRightIcon, MoreHorizontalIcon, Eye, PlusCircle, HelpCircle, Maximize2, Download, FileSpreadsheet, ChevronDown, ChevronLeft, ChevronRight, CheckCircle, XCircle, Search, Globe, User, ArrowRight, MapPin, CalendarClock, List, RefreshCw, FilePlus, XIcon, CornerUpLeftIcon, AlbumIcon, FeatherIcon, ListMinusIcon, ListPlusIcon, ListEnd, Wand, LanguagesIcon, BadgeHelpIcon, PenLineIcon, SearchIcon, MusicIcon, CompassIcon, SmileIcon, LeafIcon, ClockIcon, AppleIcon, FlagIcon, StarIcon, DeleteIcon, AlignLeft, AlignCenter, AlignRight, RotateCcw, AlertTriangle, AlertCircle, ArrowUpDown, ArrowDownToLine, PenLine, PencilIcon, TrashIcon, FileIcon, Star, ChevronsUpDown, FolderIcon, MessageSquare, Hash, Table, CheckSquare, Calendar as Calendar$1, Clock, Phone, Mail, Send, RefreshCcw, Undo2, ChevronsUpDownIcon, ChevronsRight, ChevronsLeft, CalendarDays, RefreshCwIcon, PaintRoller, MessageSquareText, ArrowLeft, Users, Bot, Brain, Lightbulb, BookOpen, PenTool, SlidersHorizontal, Wand2, Mic, Code, Trash, Edit, Share, FolderInput, Archive, Building2, ShieldCheck, Sparkles, PanelLeft, NotebookText, CirclePlus, MoreVertical, FileSearch, Microscope, Ruler, AudioLines, BrainCircuit, File as File$1, Plug, Inbox, Menu, FolderOpen, LayoutDashboard, Table2, WandSparklesIcon, ArrowUpToLineIcon, BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, HighlighterIcon, Undo2Icon, Redo2Icon, ArrowDownToLineIcon, AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifyIcon, ListOrdered, ListTodoIcon, ListCollapseIcon, Grid3x3Icon, Combine, Ungroup, ArrowUp, ArrowDown, Trash2Icon, LinkIcon, WrapText, OutdentIcon, IndentIcon, EyeIcon, PenIcon } from 'lucide-react';
13
13
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
14
14
  import { ScrollArea as ScrollArea$1 } from '@docyrus/ui-pro-shared/components/scroll-area';
15
15
  import { AsyncTokenManager, RestApiClient } from '@docyrus/api-client';
@@ -3884,6 +3884,7 @@ function useAssistantApi({
3884
3884
  const { user: configUser } = useAssistantConfig();
3885
3885
  const [agentDetails, setAgentDetails] = useState(null);
3886
3886
  const [isLoadingAgentDetails, setIsLoadingAgentDetails] = useState(!!tenantAiAgentId);
3887
+ const [subagents, setSubagents] = useState([]);
3887
3888
  const apiClientRef = useRef(apiClient);
3888
3889
  const fetchedAgentIdRef = useRef(null);
3889
3890
  apiClientRef.current = apiClient;
@@ -3894,6 +3895,7 @@ function useAssistantApi({
3894
3895
  let cancelled = false;
3895
3896
  const fetchAgentDetails = async () => {
3896
3897
  setAgentDetails(null);
3898
+ setSubagents([]);
3897
3899
  setIsLoadingAgentDetails(true);
3898
3900
  try {
3899
3901
  const response = await apiClientRef.current.get(endpoint);
@@ -3905,6 +3907,13 @@ function useAssistantApi({
3905
3907
  const name = data.name || data.agent?.agentName || data.agent?.name;
3906
3908
  const welcomeMessage = data.welcomeMessage || data.agent?.welcomeMessage;
3907
3909
  setAgentDetails({ logo: avatar, name, welcomeMessage });
3910
+ const direct = data.agent?.agents || [];
3911
+ const connected = (data.agent?.connectedAgents || []).map((c) => ({
3912
+ ...c,
3913
+ id: c.id || c.agentId,
3914
+ name: c.name || c.agentName
3915
+ }));
3916
+ setSubagents([...direct, ...connected]);
3908
3917
  } else {
3909
3918
  setAgentDetails({ logo, name: title });
3910
3919
  }
@@ -4190,6 +4199,7 @@ function useAssistantApi({
4190
4199
  return {
4191
4200
  agentDetails,
4192
4201
  isLoadingAgentDetails,
4202
+ subagents,
4193
4203
  fetchThreads,
4194
4204
  fetchProjectThreads: fetchProjectThreads2,
4195
4205
  loadThreadMessages: loadThreadMessages2,
@@ -13315,26 +13325,58 @@ function WorkCanvas({
13315
13325
  isStreaming && /* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin text-primary flex-none" })
13316
13326
  ] });
13317
13327
  }
13328
+ var stringify = (val) => {
13329
+ try {
13330
+ return typeof val === "string" ? val : JSON.stringify(val, null, 2);
13331
+ } catch {
13332
+ return String(val ?? "");
13333
+ }
13334
+ };
13335
+ var resolveAvatarUrl = (subagent) => {
13336
+ const avatar = subagent?.avatar;
13337
+ if (!avatar) {
13338
+ return null;
13339
+ }
13340
+ if (typeof avatar === "string") {
13341
+ return avatar;
13342
+ }
13343
+ return avatar.signed_url || avatar.url || null;
13344
+ };
13318
13345
  function SubagentTool({
13319
13346
  toolState,
13320
13347
  input,
13321
13348
  status,
13322
- skillName,
13323
- agentName,
13324
13349
  step,
13325
13350
  result,
13326
- agent,
13351
+ subagent,
13327
13352
  openCanvasView
13328
13353
  }) {
13354
+ const [open, setOpen] = useState(true);
13329
13355
  const [steps, setSteps] = useState([]);
13356
+ const [avatarLoaded, setAvatarLoaded] = useState(false);
13357
+ const [streamedContent, setStreamedContent] = useState("");
13330
13358
  const hasOpenedXlsx = useRef(false);
13331
13359
  const prevStep = useRef(void 0);
13360
+ const lastDeltaRef = useRef(void 0);
13332
13361
  useEffect(() => {
13333
- if (!step?.step || step === prevStep.current) return;
13362
+ const delta = result?.delta;
13363
+ if (typeof delta === "string" && delta && delta !== lastDeltaRef.current) {
13364
+ lastDeltaRef.current = delta;
13365
+ setStreamedContent((prev) => prev + delta);
13366
+ }
13367
+ }, [result?.delta]);
13368
+ const avatarUrl = useMemo(() => resolveAvatarUrl(subagent), [subagent]);
13369
+ useEffect(() => {
13370
+ setAvatarLoaded(false);
13371
+ }, [avatarUrl]);
13372
+ useEffect(() => {
13373
+ if (!step?.step || step === prevStep.current) {
13374
+ return;
13375
+ }
13334
13376
  prevStep.current = step;
13335
13377
  let message = step.step?.name || "Processing...";
13336
- if (agent?.steps) {
13337
- const stepConfig = agent.steps.find((s) => s.id === step.step?.id);
13378
+ if (Array.isArray(subagent?.steps)) {
13379
+ const stepConfig = subagent.steps.find((s) => s.id === step.step?.id);
13338
13380
  const messageTemplates = stepConfig?.messageTemplates;
13339
13381
  const template = step.eventType === "start" ? messageTemplates?.in_progress : messageTemplates?.completed;
13340
13382
  if (template) {
@@ -13342,82 +13384,139 @@ function SubagentTool({
13342
13384
  }
13343
13385
  }
13344
13386
  setSteps((prev) => [...prev, { data: step, message }]);
13345
- }, [step, agent]);
13387
+ }, [step, subagent]);
13388
+ const effectiveType = input?.type ?? result?.type ?? null;
13346
13389
  useEffect(() => {
13347
- if (input?.type === "xlsx" && status === "success" && result?.workId && !hasOpenedXlsx.current) {
13390
+ if (effectiveType === "xlsx" && status === "success" && result?.workId && !hasOpenedXlsx.current) {
13348
13391
  hasOpenedXlsx.current = true;
13349
13392
  openCanvasView?.({
13350
13393
  type: "xlsx",
13351
13394
  id: result.workId,
13352
13395
  versionId: result.workVersionId,
13396
+ workId: result.workId,
13353
13397
  title: result.title,
13354
13398
  contentJson: result.content
13355
13399
  });
13356
13400
  }
13357
13401
  }, [
13358
- input?.type,
13402
+ effectiveType,
13359
13403
  status,
13360
13404
  result,
13361
13405
  openCanvasView
13362
13406
  ]);
13407
+ const displayName = subagent?.agentName || subagent?.name || input?.agentName || "";
13363
13408
  const isLoading = toolState === "input-streaming" || status === "started";
13364
- return /* @__PURE__ */ jsxs("div", { className: "relative pl-4 ml-4 mt-4 pt-4 border-l border-slate-100", children: [
13365
- /* @__PURE__ */ jsxs("div", { className: "absolute -top-4 -left-4 rounded-full px-2 py-1 text-[10px] bg-slate-100 w-fit flex items-center gap-1", children: [
13366
- skillName && /* @__PURE__ */ jsxs(Fragment, { children: [
13367
- /* @__PURE__ */ jsx(FolderOpen, { className: "size-4" }),
13368
- /* @__PURE__ */ jsx("i", { children: skillName }),
13369
- /* @__PURE__ */ jsx("span", { children: "skill loaded" })
13370
- ] }),
13371
- agentName && /* @__PURE__ */ jsxs(Fragment, { children: [
13372
- /* @__PURE__ */ jsx(User, { className: "size-4" }),
13373
- /* @__PURE__ */ jsx("i", { children: agentName }),
13374
- /* @__PURE__ */ jsx("span", { children: "agent called" })
13375
- ] })
13376
- ] }),
13377
- isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
13378
- input?.type === "text" && /* @__PURE__ */ jsx("div", { className: "text-sm", children: result?.delta || result?.content || "" }),
13379
- input?.type === "xlsx" && (status !== "success" ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx(
13409
+ const renderBody = () => {
13410
+ if (isLoading) {
13411
+ return /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground" });
13412
+ }
13413
+ if (effectiveType === "text") {
13414
+ const content = result?.content || streamedContent;
13415
+ if (content) {
13416
+ const isStreaming = !result?.content && status !== "success";
13417
+ return /* @__PURE__ */ jsx(MessageResponse, { mode: isStreaming ? "streaming" : "static", children: content });
13418
+ }
13419
+ return /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 italic", children: "No content returned." });
13420
+ }
13421
+ if (effectiveType === "image") {
13422
+ return /* @__PURE__ */ jsx(
13423
+ preview_image_default,
13424
+ {
13425
+ title: result?.title || input?.prompt || "Generated image",
13426
+ images: result?.images || result?.url
13427
+ }
13428
+ );
13429
+ }
13430
+ if (effectiveType === "xlsx") {
13431
+ if (status !== "success") {
13432
+ return /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground" });
13433
+ }
13434
+ return /* @__PURE__ */ jsx(
13380
13435
  WorkCanvas,
13381
13436
  {
13382
13437
  title: result?.title,
13383
13438
  description: result?.description,
13384
13439
  id: result?.workId || "streaming",
13385
- content: JSON.stringify(result?.content, null, 2),
13440
+ content: stringify(result?.content),
13386
13441
  state: toolState,
13387
13442
  onOpen: () => openCanvasView?.({
13388
13443
  type: "xlsx",
13389
13444
  id: result?.workId,
13390
13445
  versionId: result?.workVersionId,
13446
+ workId: result?.workId,
13391
13447
  title: result?.title,
13392
13448
  contentJson: result?.content
13393
13449
  })
13394
13450
  }
13395
- )),
13396
- input?.type === "work" && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
13397
- steps.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-1", children: steps.map((stepItem, idx) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
13398
- /* @__PURE__ */ jsx(CheckCircle, { className: "size-4 text-green-500 flex-none" }),
13399
- /* @__PURE__ */ jsx("div", { className: "text-sm", children: stepItem.message })
13451
+ );
13452
+ }
13453
+ if (effectiveType === "work") {
13454
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
13455
+ steps.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-1 mb-2", children: steps.map((stepItem, idx) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-slate-600", children: [
13456
+ /* @__PURE__ */ jsx(CheckCircle, { className: "size-4" }),
13457
+ /* @__PURE__ */ jsx("span", { children: stepItem.message })
13400
13458
  ] }, idx)) }),
13401
13459
  status === "success" && /* @__PURE__ */ jsx(
13402
13460
  WorkCanvas,
13403
13461
  {
13404
- title: result?.title || result?.content?.layout?.title,
13405
- description: result?.description || result?.content?.layout?.description,
13462
+ title: result?.title,
13463
+ description: result?.description,
13406
13464
  id: result?.workId || "streaming",
13407
- content: JSON.stringify(result?.content, null, 2),
13465
+ content: stringify(result?.content),
13408
13466
  state: toolState,
13409
13467
  onOpen: () => openCanvasView?.({
13410
13468
  type: input?.workType,
13411
13469
  id: result?.workId || "streaming",
13412
13470
  versionId: result?.workVersionId || "streaming",
13413
- title: result?.content?.layout?.title || result?.content?.title || result?.title,
13414
- description: result?.content?.layout?.description || result?.content?.description,
13471
+ title: result?.content?.title,
13472
+ description: result?.content?.description,
13415
13473
  contentJson: result?.content
13416
13474
  })
13417
13475
  }
13418
13476
  )
13419
- ] })
13420
- ] })
13477
+ ] });
13478
+ }
13479
+ if (typeof result?.content === "string" && result.content) {
13480
+ return /* @__PURE__ */ jsx(MessageResponse, { children: result.content });
13481
+ }
13482
+ if (result) {
13483
+ return /* @__PURE__ */ jsx("pre", { className: "text-xs text-slate-600 whitespace-pre-wrap break-words", children: stringify(result) });
13484
+ }
13485
+ return /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 italic", children: "No content returned." });
13486
+ };
13487
+ return /* @__PURE__ */ jsxs("div", { className: "my-3", children: [
13488
+ /* @__PURE__ */ jsxs(
13489
+ "button",
13490
+ {
13491
+ type: "button",
13492
+ className: "flex items-center gap-1.5 text-xs text-slate-600 hover:text-slate-900 transition-colors",
13493
+ onClick: () => setOpen((o) => !o),
13494
+ children: [
13495
+ /* @__PURE__ */ jsx("span", { className: "text-slate-500", children: "Agent Called:" }),
13496
+ /* @__PURE__ */ jsx("span", { className: "size-4 rounded-full bg-slate-100 flex-shrink-0 overflow-hidden inline-flex items-center justify-center", children: avatarUrl ? /* @__PURE__ */ jsx(
13497
+ "img",
13498
+ {
13499
+ src: avatarUrl,
13500
+ alt: displayName,
13501
+ className: cn("size-4 object-cover", !avatarLoaded && "invisible"),
13502
+ onLoad: () => setAvatarLoaded(true)
13503
+ },
13504
+ avatarUrl
13505
+ ) : /* @__PURE__ */ jsx(User, { className: "size-3 text-slate-400" }) }),
13506
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-slate-900 truncate", children: displayName }),
13507
+ /* @__PURE__ */ jsx(
13508
+ ChevronDown,
13509
+ {
13510
+ className: cn(
13511
+ "size-3 text-slate-400 flex-shrink-0 transition-transform",
13512
+ !open && "-rotate-90"
13513
+ )
13514
+ }
13515
+ )
13516
+ ]
13517
+ }
13518
+ ),
13519
+ open && /* @__PURE__ */ jsx("div", { className: "mt-2 pt-2 border-t border-slate-100", children: renderBody() })
13421
13520
  ] });
13422
13521
  }
13423
13522
  var commandConfig = {
@@ -13631,7 +13730,7 @@ function TextEditorTool({
13631
13730
  isStreaming && /* @__PURE__ */ jsx(Loader2, { className: "size-6 animate-spin text-primary flex-none" })
13632
13731
  ] });
13633
13732
  }
13634
- var stringify = (val) => {
13733
+ var stringify2 = (val) => {
13635
13734
  try {
13636
13735
  return typeof val === "string" ? val : JSON.stringify(val, null, 2);
13637
13736
  } catch {
@@ -13649,7 +13748,7 @@ function GenerativeUITool({
13649
13748
  onInsertText,
13650
13749
  onReplaceText,
13651
13750
  workId,
13652
- agent
13751
+ subagents
13653
13752
  }) {
13654
13753
  const { t } = useAssistantTranslation();
13655
13754
  const emitToolAction = (decision) => {
@@ -13969,19 +14068,17 @@ function GenerativeUITool({
13969
14068
  }
13970
14069
  if (toolName.startsWith("call") && toolName.endsWith("Agent") && (part.state === "input-available" || part.state === "input-streaming" || part.state === "output-available")) {
13971
14070
  const output = part.output;
14071
+ const agentId = output?.result?.agentId || part.input?.agentId;
14072
+ const subagent = agentId && subagents?.length ? subagents.find((a) => (a.id || a.agentId) === agentId) || null : null;
13972
14073
  return /* @__PURE__ */ jsx("div", { className: "not-prose mb-4 w-full", children: /* @__PURE__ */ jsx(
13973
14074
  SubagentTool,
13974
14075
  {
13975
14076
  toolState: part.state,
13976
14077
  input: part.input,
13977
14078
  status: output?.status,
13978
- text: output?.text,
13979
- icon: output?.icon,
13980
- skillName: output?.skillName,
13981
- agentName: output?.agentName,
13982
14079
  step: output?.step,
13983
14080
  result: output?.result,
13984
- agent,
14081
+ subagent,
13985
14082
  openCanvasView
13986
14083
  }
13987
14084
  ) });
@@ -14106,7 +14203,7 @@ function GenerativeUITool({
14106
14203
  if (part.state === "output-available") {
14107
14204
  return /* @__PURE__ */ jsx("div", { className: "not-prose mb-4 w-full", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-3", children: [
14108
14205
  /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: t("sections.output") }),
14109
- /* @__PURE__ */ jsx(CodeBlock, { code: stringify(part.output), language: "json", children: /* @__PURE__ */ jsx(CodeBlockCopyButton, {}) })
14206
+ /* @__PURE__ */ jsx(CodeBlock, { code: stringify2(part.output), language: "json", children: /* @__PURE__ */ jsx(CodeBlockCopyButton, {}) })
14110
14207
  ] }) });
14111
14208
  }
14112
14209
  if (part.state === "output-error") {
@@ -14376,7 +14473,8 @@ var MessageItem = memo(({
14376
14473
  onToolAction: onToolAction ?? (() => {
14377
14474
  }),
14378
14475
  openCanvasView,
14379
- onForwardToAgent
14476
+ onForwardToAgent,
14477
+ subagents: agents
14380
14478
  },
14381
14479
  `${messageId}-gentool-${idx}`
14382
14480
  );
@@ -14614,7 +14712,8 @@ function ChatPanel({
14614
14712
  onSessionClick,
14615
14713
  threadId,
14616
14714
  initialModelId,
14617
- initialFeatures
14715
+ initialFeatures,
14716
+ subagents
14618
14717
  }) {
14619
14718
  const renderInputArea = (hideFooter = false) => /* @__PURE__ */ jsx(
14620
14719
  AIInputArea,
@@ -14707,6 +14806,7 @@ function ChatPanel({
14707
14806
  welcomeMessage,
14708
14807
  isLoadingAgent,
14709
14808
  agentId: tenantAiAgentId,
14809
+ agents: subagents,
14710
14810
  onToolAction,
14711
14811
  openCanvasView,
14712
14812
  onEditPrompt,
@@ -29816,6 +29916,7 @@ var AssistantView = ({ ref, ...props }) => {
29816
29916
  threadId: commonProps2.threadId,
29817
29917
  initialModelId: commonProps2.initialModelId,
29818
29918
  initialFeatures: commonProps2.initialFeatures,
29919
+ subagents: commonProps2.subagents,
29819
29920
  messagesClassName: "p-4"
29820
29921
  }
29821
29922
  );
@@ -30275,6 +30376,7 @@ var AssistantView = ({ ref, ...props }) => {
30275
30376
  threadId: commonProps.threadId,
30276
30377
  initialModelId: commonProps.initialModelId,
30277
30378
  initialFeatures: commonProps.initialFeatures,
30379
+ subagents: commonProps.subagents,
30278
30380
  compactToolbar: !isFullscreen
30279
30381
  }
30280
30382
  )
@@ -31789,7 +31891,7 @@ var DocyAssistant = ({
31789
31891
  ]);
31790
31892
  const apiClientRef = useRef(apiClient);
31791
31893
  apiClientRef.current = apiClient;
31792
- const { agentDetails, isLoadingAgentDetails } = useAssistantApi({
31894
+ const { agentDetails, isLoadingAgentDetails, subagents } = useAssistantApi({
31793
31895
  tenantAiAgentId: activeAgentId,
31794
31896
  deploymentId,
31795
31897
  logo,
@@ -32210,6 +32312,7 @@ var DocyAssistant = ({
32210
32312
  supportMultiModels,
32211
32313
  deploymentId,
32212
32314
  tenantAiAgentId: activeAgentId,
32315
+ subagents,
32213
32316
  initialModelId,
32214
32317
  initialFeatures,
32215
32318
  enableMicrophone,