@mastra/playground-ui 6.1.2 → 6.1.3-alpha.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/dist/index.cjs.js CHANGED
@@ -20,6 +20,7 @@ const highlight$1 = require('@lezer/highlight');
20
20
  const codemirrorThemeDracula = require('@uiw/codemirror-theme-dracula');
21
21
  const CodeMirror = require('@uiw/react-codemirror');
22
22
  const sonner = require('sonner');
23
+ const DialogPrimitive = require('@radix-ui/react-dialog');
23
24
  const useDebounce = require('use-debounce');
24
25
  const reactQuery = require('@tanstack/react-query');
25
26
  const react = require('@xyflow/react');
@@ -27,7 +28,6 @@ require('@xyflow/react/dist/style.css');
27
28
  const Dagre = require('@dagrejs/dagre');
28
29
  const prismReactRenderer = require('prism-react-renderer');
29
30
  const CollapsiblePrimitive = require('@radix-ui/react-collapsible');
30
- const DialogPrimitive = require('@radix-ui/react-dialog');
31
31
  const ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
32
32
  const prettier = require('prettier');
33
33
  const prettierPluginBabel = require('prettier/plugins/babel');
@@ -85,8 +85,8 @@ function _interopNamespaceDefault(e) {
85
85
  const React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
86
86
  const TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TooltipPrimitive);
87
87
  const AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(AvatarPrimitive);
88
- const CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CollapsiblePrimitive);
89
88
  const DialogPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(DialogPrimitive);
89
+ const CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CollapsiblePrimitive);
90
90
  const ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(ScrollAreaPrimitive);
91
91
  const CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CheckboxPrimitive);
92
92
  const PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(PopoverPrimitive);
@@ -4374,45 +4374,173 @@ const BadgeWrapper = ({
4374
4374
  initialCollapsed = true,
4375
4375
  icon,
4376
4376
  title,
4377
- collapsible = true
4377
+ collapsible = true,
4378
+ extraInfo
4378
4379
  }) => {
4379
4380
  const [isCollapsed, setIsCollapsed] = React.useState(initialCollapsed);
4380
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
4381
- /* @__PURE__ */ jsxRuntime.jsxs(
4382
- "button",
4381
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
4382
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row gap-2 items-center justify-between", children: [
4383
+ /* @__PURE__ */ jsxRuntime.jsxs(
4384
+ "button",
4385
+ {
4386
+ onClick: collapsible ? () => setIsCollapsed((s) => !s) : void 0,
4387
+ className: "flex items-center gap-2 disabled:cursor-not-allowed",
4388
+ disabled: !collapsible,
4389
+ type: "button",
4390
+ children: [
4391
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: cn("transition-all", isCollapsed ? "rotate-90" : "rotate-180") }) }),
4392
+ /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon, children: title })
4393
+ ]
4394
+ }
4395
+ ),
4396
+ extraInfo
4397
+ ] }),
4398
+ !isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 rounded-lg bg-surface2 flex flex-col gap-4", children }) })
4399
+ ] });
4400
+ };
4401
+
4402
+ const Dialog = DialogPrimitive__namespace.Root;
4403
+ const DialogPortal = DialogPrimitive__namespace.Portal;
4404
+ const DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4405
+ DialogPrimitive__namespace.Overlay,
4406
+ {
4407
+ ref,
4408
+ className: cn(
4409
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4410
+ className
4411
+ ),
4412
+ ...props
4413
+ }
4414
+ ));
4415
+ DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
4416
+ const DialogContent = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
4417
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
4418
+ /* @__PURE__ */ jsxRuntime.jsxs(
4419
+ DialogPrimitive__namespace.Content,
4420
+ {
4421
+ ref,
4422
+ className: cn(
4423
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
4424
+ className
4425
+ ),
4426
+ ...props,
4427
+ children: [
4428
+ children,
4429
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
4430
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
4431
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
4432
+ ] })
4433
+ ]
4434
+ }
4435
+ )
4436
+ ] }));
4437
+ DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
4438
+ const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
4439
+ DialogHeader.displayName = "DialogHeader";
4440
+ const DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4441
+ DialogPrimitive__namespace.Title,
4442
+ {
4443
+ ref,
4444
+ className: clsx("text-lg font-semibold leading-none tracking-tight", className),
4445
+ ...props
4446
+ }
4447
+ ));
4448
+ DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
4449
+ const DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
4450
+ DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
4451
+
4452
+ const variants = {
4453
+ "header-md": "text-header-md leading-header-md",
4454
+ "ui-lg": "text-ui-lg leading-ui-lg",
4455
+ "ui-md": "text-ui-md leading-ui-md",
4456
+ "ui-sm": "text-ui-sm leading-ui-sm",
4457
+ "ui-xs": "text-ui-xs leading-ui-xs"
4458
+ };
4459
+ const fonts = {
4460
+ mono: "font-mono"
4461
+ };
4462
+ const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
4463
+ return /* @__PURE__ */ jsxRuntime.jsx(Root, { className: clsx(variants[variant], font && fonts[font], className), ...props });
4464
+ };
4465
+
4466
+ const NetworkChoiceMetadata = ({ selectionReason, open, onOpenChange, input }) => {
4467
+ let inputSlot = null;
4468
+ if (input) {
4469
+ try {
4470
+ inputSlot = typeof input === "object" ? /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: input }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: JSON.parse(input) });
4471
+ } catch {
4472
+ inputSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: input });
4473
+ }
4474
+ }
4475
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "border-border1 border-sm bg-surface3 p-0 gap-0", children: [
4476
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "p-4", children: [
4477
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Agent Network Metadata" }),
4478
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "View the metadata of the agent's network choice." })
4479
+ ] }),
4480
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 p-4 border-t-sm border-border1", children: [
4481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
4482
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3", children: "Selection Reason" }),
4483
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-icon6 text-ui-md", children: selectionReason })
4484
+ ] }),
4485
+ inputSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
4486
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { className: "text-icon3", children: "Input" }),
4487
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-icon6 text-ui-md", children: inputSlot })
4488
+ ] })
4489
+ ] })
4490
+ ] }) });
4491
+ };
4492
+ const NetworkChoiceMetadataDialogTrigger = ({
4493
+ selectionReason,
4494
+ input
4495
+ }) => {
4496
+ const [isOpen, setIsOpen] = React.useState(false);
4497
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4498
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Show selection reason", side: "top", onClick: () => setIsOpen((s) => !s), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Share2, { className: "text-icon3 size-5" }) }),
4499
+ /* @__PURE__ */ jsxRuntime.jsx(
4500
+ NetworkChoiceMetadata,
4383
4501
  {
4384
- onClick: collapsible ? () => setIsCollapsed((s) => !s) : void 0,
4385
- className: "flex items-center gap-2 disabled:cursor-not-allowed",
4386
- disabled: !collapsible,
4387
- type: "button",
4388
- children: [
4389
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: cn("transition-all", isCollapsed ? "rotate-90" : "rotate-180") }) }),
4390
- /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon, children: title })
4391
- ]
4502
+ selectionReason: selectionReason || "",
4503
+ open: isOpen,
4504
+ onOpenChange: setIsOpen,
4505
+ input
4392
4506
  }
4393
- ),
4394
- !isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 rounded-lg bg-surface2", children }) })
4507
+ )
4395
4508
  ] });
4396
4509
  };
4397
4510
 
4398
- const ToolBadge = ({ toolName, argsText, result }) => {
4399
- let argSlot;
4511
+ const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4512
+ let argSlot = null;
4400
4513
  try {
4401
- const parsedArgs = JSON.parse(argsText);
4402
- argSlot = /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: parsedArgs });
4514
+ const { __mastraMetadata: _, ...formattedArgs } = typeof args === "object" ? args : JSON.parse(args);
4515
+ argSlot = /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: formattedArgs });
4403
4516
  } catch {
4404
- argSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: argsText });
4517
+ argSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: args });
4405
4518
  }
4406
- return /* @__PURE__ */ jsxRuntime.jsx(BadgeWrapper, { icon: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, { className: "text-[#ECB047]" }), title: toolName, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
4407
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4408
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4409
- argSlot
4410
- ] }),
4411
- result !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4412
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4413
- typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result })
4414
- ] })
4415
- ] }) });
4519
+ let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result });
4520
+ return /* @__PURE__ */ jsxRuntime.jsx(
4521
+ BadgeWrapper,
4522
+ {
4523
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, { className: "text-[#ECB047]" }),
4524
+ title: toolName,
4525
+ extraInfo: networkMetadata && /* @__PURE__ */ jsxRuntime.jsx(
4526
+ NetworkChoiceMetadataDialogTrigger,
4527
+ {
4528
+ selectionReason: networkMetadata?.selectionReason || "",
4529
+ input: networkMetadata?.input
4530
+ }
4531
+ ),
4532
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
4533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4534
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4535
+ argSlot
4536
+ ] }),
4537
+ result !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4538
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4539
+ resultSlot
4540
+ ] })
4541
+ ] })
4542
+ }
4543
+ );
4416
4544
  };
4417
4545
 
4418
4546
  function Skeleton({ className, ...props }) {
@@ -4424,7 +4552,8 @@ const useWorkflow = (workflowId) => {
4424
4552
  return reactQuery.useQuery({
4425
4553
  queryKey: ["workflow", workflowId],
4426
4554
  queryFn: () => client.getWorkflow(workflowId).details(),
4427
- retry: false
4555
+ retry: false,
4556
+ refetchOnWindowFocus: false
4428
4557
  });
4429
4558
  };
4430
4559
  const useLegacyWorkflow = (workflowId) => {
@@ -5303,56 +5432,6 @@ const CollapsibleTrigger = (props) => {
5303
5432
  };
5304
5433
  const CollapsibleContent = CollapsiblePrimitive__namespace.CollapsibleContent;
5305
5434
 
5306
- const Dialog = DialogPrimitive__namespace.Root;
5307
- const DialogPortal = DialogPrimitive__namespace.Portal;
5308
- const DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5309
- DialogPrimitive__namespace.Overlay,
5310
- {
5311
- ref,
5312
- className: cn(
5313
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5314
- className
5315
- ),
5316
- ...props
5317
- }
5318
- ));
5319
- DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
5320
- const DialogContent = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
5321
- /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
5322
- /* @__PURE__ */ jsxRuntime.jsxs(
5323
- DialogPrimitive__namespace.Content,
5324
- {
5325
- ref,
5326
- className: cn(
5327
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
5328
- className
5329
- ),
5330
- ...props,
5331
- children: [
5332
- children,
5333
- /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
5334
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
5335
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
5336
- ] })
5337
- ]
5338
- }
5339
- )
5340
- ] }));
5341
- DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
5342
- const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
5343
- DialogHeader.displayName = "DialogHeader";
5344
- const DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5345
- DialogPrimitive__namespace.Title,
5346
- {
5347
- ref,
5348
- className: clsx("text-lg font-semibold leading-none tracking-tight", className),
5349
- ...props
5350
- }
5351
- ));
5352
- DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
5353
- const DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
5354
- DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
5355
-
5356
5435
  const useAutoscroll = (ref, { enabled = true }) => {
5357
5436
  const shouldScrollRef = React.useRef(enabled);
5358
5437
  React.useEffect(() => {
@@ -5504,9 +5583,9 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5504
5583
  ...chunk.payload
5505
5584
  },
5506
5585
  workflowState: {
5507
- ...prev.payload.workflowState,
5586
+ ...prev?.payload?.workflowState,
5508
5587
  steps: {
5509
- ...prev.payload.workflowState.steps,
5588
+ ...prev?.payload?.workflowState?.steps,
5510
5589
  [chunk.payload.id]: {
5511
5590
  ...current || {},
5512
5591
  ...chunk.payload
@@ -5522,17 +5601,17 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5522
5601
  return {
5523
5602
  ...prev,
5524
5603
  payload: {
5525
- ...prev.payload,
5604
+ ...prev?.payload,
5526
5605
  currentStep: {
5527
5606
  id: chunk.payload.id,
5528
- ...prev?.payload?.currentStep || {},
5607
+ ...prev?.payload?.currentStep,
5529
5608
  ...chunk.payload
5530
5609
  },
5531
5610
  workflowState: {
5532
- ...prev.payload.workflowState,
5611
+ ...prev?.payload?.workflowState,
5533
5612
  status: "suspended",
5534
5613
  steps: {
5535
- ...prev.payload.workflowState.steps,
5614
+ ...prev?.payload?.workflowState?.steps,
5536
5615
  [chunk.payload.id]: {
5537
5616
  ...current || {},
5538
5617
  ...chunk.payload
@@ -5548,17 +5627,17 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5548
5627
  return {
5549
5628
  ...prev,
5550
5629
  payload: {
5551
- ...prev.payload,
5630
+ ...prev?.payload,
5552
5631
  currentStep: {
5553
5632
  id: chunk.payload.id,
5554
5633
  ...prev?.payload?.currentStep || {},
5555
5634
  ...chunk.payload
5556
5635
  },
5557
5636
  workflowState: {
5558
- ...prev.payload.workflowState,
5637
+ ...prev?.payload?.workflowState,
5559
5638
  status: "waiting",
5560
5639
  steps: {
5561
- ...prev.payload.workflowState.steps,
5640
+ ...prev?.payload?.workflowState?.steps,
5562
5641
  [chunk.payload.id]: {
5563
5642
  ...current,
5564
5643
  ...chunk.payload
@@ -5572,20 +5651,20 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5572
5651
  if (chunk.type === "workflow-step-result") {
5573
5652
  const status = chunk.payload.status;
5574
5653
  const current = prev?.payload?.workflowState?.steps?.[chunk.payload.id] || {};
5575
- return {
5654
+ const next = {
5576
5655
  ...prev,
5577
5656
  payload: {
5578
- ...prev.payload,
5657
+ ...prev?.payload,
5579
5658
  currentStep: {
5580
5659
  id: chunk.payload.id,
5581
5660
  ...prev?.payload?.currentStep || {},
5582
5661
  ...chunk.payload
5583
5662
  },
5584
5663
  workflowState: {
5585
- ...prev.payload.workflowState,
5664
+ ...prev?.payload?.workflowState,
5586
5665
  status,
5587
5666
  steps: {
5588
- ...prev.payload.workflowState.steps,
5667
+ ...prev?.payload?.workflowState?.steps,
5589
5668
  [chunk.payload.id]: {
5590
5669
  ...current,
5591
5670
  ...chunk.payload
@@ -5595,14 +5674,15 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5595
5674
  },
5596
5675
  eventTimestamp: /* @__PURE__ */ new Date()
5597
5676
  };
5677
+ return next;
5598
5678
  }
5599
5679
  if (chunk.type === "workflow-canceled") {
5600
5680
  return {
5601
5681
  ...prev,
5602
5682
  payload: {
5603
- ...prev.payload,
5683
+ ...prev?.payload,
5604
5684
  workflowState: {
5605
- ...prev.payload.workflowState,
5685
+ ...prev?.payload?.workflowState,
5606
5686
  status: "canceled"
5607
5687
  }
5608
5688
  },
@@ -5613,10 +5693,10 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
5613
5693
  return {
5614
5694
  ...prev,
5615
5695
  payload: {
5616
- ...prev.payload,
5696
+ ...prev?.payload,
5617
5697
  currentStep: void 0,
5618
5698
  workflowState: {
5619
- ...prev.payload.workflowState,
5699
+ ...prev?.payload?.workflowState,
5620
5700
  status: chunk.payload.workflowStatus
5621
5701
  }
5622
5702
  },
@@ -5644,10 +5724,8 @@ function WorkflowRunProvider({
5644
5724
  React.useEffect(() => {
5645
5725
  if (snapshot?.runId) {
5646
5726
  setResult(convertWorkflowRunStateToWatchResult(snapshot));
5647
- } else {
5648
- setResult(null);
5649
5727
  }
5650
- }, [snapshot?.runId ?? ""]);
5728
+ }, [snapshot]);
5651
5729
  return /* @__PURE__ */ jsxRuntime.jsx(
5652
5730
  WorkflowRunContext.Provider,
5653
5731
  {
@@ -5757,20 +5835,6 @@ const CodeDialogContent = ({ data }) => {
5757
5835
  }
5758
5836
  };
5759
5837
 
5760
- const variants = {
5761
- "header-md": "text-header-md leading-header-md",
5762
- "ui-lg": "text-ui-lg leading-ui-lg",
5763
- "ui-md": "text-ui-md leading-ui-md",
5764
- "ui-sm": "text-ui-sm leading-ui-sm",
5765
- "ui-xs": "text-ui-xs leading-ui-xs"
5766
- };
5767
- const fonts = {
5768
- mono: "font-mono"
5769
- };
5770
- const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
5771
- return /* @__PURE__ */ jsxRuntime.jsx(Root, { className: clsx(variants[variant], font && fonts[font], className), ...props });
5772
- };
5773
-
5774
5838
  const formatJSON = async (code) => {
5775
5839
  const formatted = await prettier.format(code, {
5776
5840
  semi: false,
@@ -6647,7 +6711,7 @@ const PopoverContent = React__namespace.forwardRef(({ className, align = "center
6647
6711
  ref,
6648
6712
  align,
6649
6713
  sideOffset,
6650
- className: cn(
6714
+ className: clsx(
6651
6715
  "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
6652
6716
  className
6653
6717
  ),
@@ -8005,7 +8069,7 @@ function WorkflowTrigger({
8005
8069
  }, [isStreamingWorkflow]);
8006
8070
  React.useEffect(() => {
8007
8071
  if (!streamResultToUse?.payload?.workflowState?.steps || !result?.runId) return;
8008
- const suspended = Object.entries(streamResultToUse.payload.workflowState.steps).filter(([_, { status }]) => status === "suspended").map(([stepId, { payload: payload2 }]) => ({
8072
+ const suspended = Object.entries(streamResultToUse?.payload?.workflowState?.steps || {}).filter(([_, { status }]) => status === "suspended").map(([stepId, { payload: payload2 }]) => ({
8009
8073
  stepId,
8010
8074
  runId: result.runId,
8011
8075
  suspendPayload: payload2,
@@ -8538,15 +8602,6 @@ const EmptyWorkflowsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { classN
8538
8602
  }
8539
8603
  ) });
8540
8604
 
8541
- const useHandleAgentWorkflowStream = (workflowOutput) => {
8542
- const [streamResult, setStreamResult] = React.useState({});
8543
- React.useEffect(() => {
8544
- if (!workflowOutput) return;
8545
- setStreamResult((prev) => mapWorkflowStreamChunkToWatchResult(prev, workflowOutput));
8546
- }, [workflowOutput]);
8547
- return streamResult;
8548
- };
8549
-
8550
8605
  const useWorkflowRuns = (workflowId, { enabled = true } = {}) => {
8551
8606
  const client = useMastraClient();
8552
8607
  return reactQuery.useQuery({
@@ -8556,17 +8611,32 @@ const useWorkflowRuns = (workflowId, { enabled = true } = {}) => {
8556
8611
  });
8557
8612
  };
8558
8613
 
8559
- const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming }) => {
8614
+ const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming, networkMetadata }) => {
8560
8615
  const { data: runs, isLoading: isRunsLoading } = useWorkflowRuns(workflowId, {
8561
8616
  enabled: Boolean(runId) && !isStreaming
8562
8617
  });
8563
8618
  const run = runs?.runs.find((run2) => run2.runId === runId);
8564
8619
  const isLoading = isRunsLoading || !run;
8565
8620
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
8566
- return /* @__PURE__ */ jsxRuntime.jsxs(BadgeWrapper, { icon: /* @__PURE__ */ jsxRuntime.jsx(WorkflowIcon, { className: "text-accent3" }), title: workflow.name, initialCollapsed: false, children: [
8567
- !isStreaming && !isLoading && /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { snapshot, children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }) }),
8568
- isStreaming && /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId })
8569
- ] });
8621
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8622
+ BadgeWrapper,
8623
+ {
8624
+ icon: /* @__PURE__ */ jsxRuntime.jsx(WorkflowIcon, { className: "text-accent3" }),
8625
+ title: workflow.name,
8626
+ initialCollapsed: false,
8627
+ extraInfo: networkMetadata && /* @__PURE__ */ jsxRuntime.jsx(
8628
+ NetworkChoiceMetadataDialogTrigger,
8629
+ {
8630
+ selectionReason: networkMetadata?.selectionReason || "",
8631
+ input: networkMetadata?.input
8632
+ }
8633
+ ),
8634
+ children: [
8635
+ !isStreaming && !isLoading && /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { snapshot, children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId }) }),
8636
+ isStreaming && /* @__PURE__ */ jsxRuntime.jsx(WorkflowBadgeExtended, { workflowId, workflow, runId })
8637
+ ]
8638
+ }
8639
+ );
8570
8640
  };
8571
8641
  const WorkflowBadgeExtended = ({ workflowId, workflow, runId }) => {
8572
8642
  const { Link } = useLinkComponent();
@@ -8578,13 +8648,12 @@ const WorkflowBadgeExtended = ({ workflowId, workflow, runId }) => {
8578
8648
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md overflow-hidden h-[60vh] w-full", children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowGraph, { workflowId, workflow }) })
8579
8649
  ] });
8580
8650
  };
8581
- const useWorkflowStream = (partialWorkflowOutput) => {
8582
- const streamResult = useHandleAgentWorkflowStream(partialWorkflowOutput);
8651
+ const useWorkflowStream = (workflowFullState) => {
8583
8652
  const { setResult } = React.useContext(WorkflowRunContext);
8584
8653
  React.useEffect(() => {
8585
- if (!streamResult) return;
8586
- setResult(streamResult);
8587
- }, [streamResult]);
8654
+ if (!workflowFullState) return;
8655
+ setResult(workflowFullState);
8656
+ }, [workflowFullState]);
8588
8657
  };
8589
8658
 
8590
8659
  const LoadingBadge = () => {
@@ -8598,12 +8667,61 @@ const LoadingBadge = () => {
8598
8667
  );
8599
8668
  };
8600
8669
 
8601
- const ToolFallback$1 = ({ toolName, argsText, result, args, ...props }) => {
8602
- return /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolFallbackInner, { toolName, argsText, result, args, ...props }) });
8670
+ const AgentBadge = ({ agentId, messages = [], networkMetadata }) => {
8671
+ return /* @__PURE__ */ jsxRuntime.jsx(
8672
+ BadgeWrapper,
8673
+ {
8674
+ icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, { className: "text-accent1" }),
8675
+ title: agentId,
8676
+ initialCollapsed: false,
8677
+ extraInfo: networkMetadata && /* @__PURE__ */ jsxRuntime.jsx(
8678
+ NetworkChoiceMetadataDialogTrigger,
8679
+ {
8680
+ selectionReason: networkMetadata?.selectionReason || "",
8681
+ input: networkMetadata?.input
8682
+ }
8683
+ ),
8684
+ children: messages.map((message, index) => {
8685
+ if (message.type === "text") {
8686
+ return /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: message.content }, index);
8687
+ }
8688
+ const result = typeof message.toolOutput === "string" ? JSON.parse(message.toolOutput) : message.toolOutput;
8689
+ return /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
8690
+ ToolFallback$1,
8691
+ {
8692
+ toolName: message.toolName,
8693
+ argsText: typeof message.args === "string" ? message.args : JSON.stringify(message.args),
8694
+ result,
8695
+ args: message.args,
8696
+ status: { type: "complete" },
8697
+ type: "tool-call",
8698
+ toolCallId: message.toolCallId,
8699
+ addResult: () => {
8700
+ }
8701
+ }
8702
+ ) }, index);
8703
+ })
8704
+ }
8705
+ );
8706
+ };
8707
+
8708
+ const ToolFallback$1 = ({ toolName, result, args, ...props }) => {
8709
+ return /* @__PURE__ */ jsxRuntime.jsx(WorkflowRunProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolFallbackInner, { toolName, result, args, ...props }) });
8603
8710
  };
8604
- const ToolFallbackInner = ({ toolName, argsText, result, args }) => {
8605
- useWorkflowStream(args.__mastraMetadata?.partialChunk);
8711
+ const ToolFallbackInner = ({ toolName, result, args }) => {
8712
+ useWorkflowStream(args.__mastraMetadata?.workflowFullState);
8606
8713
  const { data: workflow, isLoading } = useWorkflow(toolName);
8714
+ const isAgent = args.__mastraMetadata?.from === "AGENT";
8715
+ if (isAgent) {
8716
+ return /* @__PURE__ */ jsxRuntime.jsx(
8717
+ AgentBadge,
8718
+ {
8719
+ agentId: toolName,
8720
+ messages: args?.__mastraMetadata?.messages,
8721
+ networkMetadata: args?.__mastraMetadata?.networkMetadata
8722
+ }
8723
+ );
8724
+ }
8607
8725
  if (isLoading) return /* @__PURE__ */ jsxRuntime.jsx(LoadingBadge, {});
8608
8726
  if (workflow) {
8609
8727
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -8612,11 +8730,20 @@ const ToolFallbackInner = ({ toolName, argsText, result, args }) => {
8612
8730
  workflowId: toolName,
8613
8731
  workflow,
8614
8732
  isStreaming: args.__mastraMetadata?.isStreaming,
8615
- runId: result?.runId
8733
+ runId: result?.runId,
8734
+ networkMetadata: args?.__mastraMetadata?.networkMetadata
8616
8735
  }
8617
8736
  );
8618
8737
  }
8619
- return /* @__PURE__ */ jsxRuntime.jsx(ToolBadge, { toolName, argsText, result });
8738
+ return /* @__PURE__ */ jsxRuntime.jsx(
8739
+ ToolBadge,
8740
+ {
8741
+ toolName,
8742
+ args,
8743
+ result,
8744
+ networkMetadata: args?.__mastraMetadata?.networkMetadata
8745
+ }
8746
+ );
8620
8747
  };
8621
8748
 
8622
8749
  const Reasoning = ({ text }) => {
@@ -9220,7 +9347,20 @@ const AttachFileDialog = ({ onOpenChange, open }) => {
9220
9347
  ] }) });
9221
9348
  };
9222
9349
 
9223
- const Thread = ({ ToolFallback, agentName, agentId, hasMemory, onInputChange }) => {
9350
+ const ThreadInputContext = React.createContext({
9351
+ threadInput: "",
9352
+ setThreadInput: () => {
9353
+ }
9354
+ });
9355
+ const ThreadInputProvider = ({ children }) => {
9356
+ const [threadInput, setThreadInput] = React.useState("");
9357
+ return /* @__PURE__ */ jsxRuntime.jsx(ThreadInputContext.Provider, { value: { threadInput, setThreadInput }, children });
9358
+ };
9359
+ const useThreadInput = () => {
9360
+ return React.useContext(ThreadInputContext);
9361
+ };
9362
+
9363
+ const Thread = ({ ToolFallback, agentName, agentId, hasMemory }) => {
9224
9364
  const areaRef = React.useRef(null);
9225
9365
  useAutoscroll(areaRef, { enabled: true });
9226
9366
  const WrappedAssistantMessage = (props) => {
@@ -9241,7 +9381,7 @@ const Thread = ({ ToolFallback, agentName, agentId, hasMemory, onInputChange })
9241
9381
  ) }),
9242
9382
  /* @__PURE__ */ jsxRuntime.jsx(react$2.ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsxRuntime.jsx("div", {}) })
9243
9383
  ] }),
9244
- /* @__PURE__ */ jsxRuntime.jsx(Composer$1, { hasMemory, onInputChange, agentId })
9384
+ /* @__PURE__ */ jsxRuntime.jsx(Composer$1, { hasMemory, agentId })
9245
9385
  ] });
9246
9386
  };
9247
9387
  const ThreadWrapper$1 = ({ children }) => {
@@ -9263,7 +9403,8 @@ const ThreadWelcome$1 = ({ agentName }) => {
9263
9403
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
9264
9404
  ] }) });
9265
9405
  };
9266
- const Composer$1 = ({ hasMemory, onInputChange, agentId }) => {
9406
+ const Composer$1 = ({ hasMemory, agentId }) => {
9407
+ const { setThreadInput } = useThreadInput();
9267
9408
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4", children: [
9268
9409
  /* @__PURE__ */ jsxRuntime.jsxs(react$2.ComposerPrimitive.Root, { children: [
9269
9410
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ComposerAttachments, {}) }),
@@ -9276,7 +9417,7 @@ const Composer$1 = ({ hasMemory, onInputChange, agentId }) => {
9276
9417
  placeholder: "Enter your message...",
9277
9418
  name: "",
9278
9419
  id: "",
9279
- onChange: (e) => onInputChange?.(e.target.value)
9420
+ onChange: (e) => setThreadInput?.(e.target.value)
9280
9421
  }
9281
9422
  ) }),
9282
9423
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
@@ -9604,21 +9745,550 @@ const useAdapters = (agentId) => {
9604
9745
  };
9605
9746
  };
9606
9747
 
9607
- const convertMessage$2 = (message) => {
9608
- return message;
9609
- };
9610
- const handleFinishReason = (finishReason) => {
9611
- switch (finishReason) {
9612
- case "tool-calls":
9613
- throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
9614
- }
9615
- };
9616
- const convertToAIAttachments = async (attachments) => {
9617
- const promises = (attachments ?? []).filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
9618
- const isFileFromURL = attachment.name.startsWith("https://");
9619
- if (attachment.type === "document") {
9620
- if (attachment.contentType === "application/pdf") {
9621
- const pdfText = attachment.content?.[0]?.text || "";
9748
+ const handleNetworkMessageFromMemory = (content) => {
9749
+ if (content.resourceType === "workflow") {
9750
+ return {
9751
+ role: "assistant",
9752
+ content: [
9753
+ {
9754
+ type: "tool-call",
9755
+ toolCallId: content.finalResult.runId,
9756
+ toolName: content.resourceId,
9757
+ result: { runId: content.finalResult.runId },
9758
+ args: {
9759
+ __mastraMetadata: {
9760
+ from: "WORKFLOW",
9761
+ networkMetadata: {
9762
+ selectionReason: content?.selectionReason,
9763
+ input: content?.input
9764
+ }
9765
+ }
9766
+ }
9767
+ }
9768
+ ]
9769
+ };
9770
+ }
9771
+ if (content.resourceType === "agent") {
9772
+ const badgeMessages = [];
9773
+ let toolCalls = {};
9774
+ const messages = content.finalResult.messages.slice(1);
9775
+ for (const message of messages) {
9776
+ if (typeof message.content === "string") {
9777
+ badgeMessages.push({
9778
+ type: "text",
9779
+ content: message.content
9780
+ });
9781
+ continue;
9782
+ }
9783
+ for (const part of message.content) {
9784
+ if (part.type === "text") {
9785
+ badgeMessages.push({
9786
+ type: "text",
9787
+ content: part.content
9788
+ });
9789
+ } else if (part.type === "tool-result") {
9790
+ badgeMessages.push({
9791
+ type: "tool",
9792
+ toolName: part.toolName,
9793
+ toolOutput: part.result,
9794
+ // tool output
9795
+ toolCallId: part.toolCallId,
9796
+ args: toolCalls?.[part.toolCallId]?.args || {}
9797
+ });
9798
+ } else if (part.type === "tool-call") {
9799
+ toolCalls[part.toolCallId] = part;
9800
+ }
9801
+ }
9802
+ }
9803
+ return {
9804
+ role: "assistant",
9805
+ content: [
9806
+ {
9807
+ type: "tool-call",
9808
+ toolCallId: content.finalResult.runId,
9809
+ toolName: content.resourceId,
9810
+ result: { runId: content.finalResult.runId },
9811
+ args: {
9812
+ __mastraMetadata: {
9813
+ from: "AGENT",
9814
+ networkMetadata: {
9815
+ selectionReason: content?.selectionReason || "",
9816
+ input: content?.input || ""
9817
+ },
9818
+ messages: badgeMessages
9819
+ }
9820
+ }
9821
+ }
9822
+ ]
9823
+ };
9824
+ }
9825
+ if (content.resourceType === "tool") {
9826
+ return {
9827
+ role: "assistant",
9828
+ content: [
9829
+ {
9830
+ type: "tool-call",
9831
+ toolCallId: content.finalResult.toolCallId,
9832
+ toolName: content.resourceId,
9833
+ result: content.finalResult.result,
9834
+ args: {
9835
+ ...content?.input,
9836
+ __mastraMetadata: {
9837
+ networkMetadata: {
9838
+ selectionReason: content?.selectionReason || "",
9839
+ input: content?.input || ""
9840
+ }
9841
+ }
9842
+ }
9843
+ }
9844
+ ]
9845
+ };
9846
+ }
9847
+ return { role: "assistant", content: [{ type: "text", text: "Unknown response" }] };
9848
+ };
9849
+
9850
+ const handleStreamChunk = async ({
9851
+ chunk,
9852
+ setMessages,
9853
+ refreshWorkingMemory,
9854
+ _sideEffects
9855
+ }) => {
9856
+ function updater() {
9857
+ setMessages((currentConversation) => {
9858
+ const message = {
9859
+ role: "assistant",
9860
+ content: [{ type: "text", text: _sideEffects.content }]
9861
+ };
9862
+ if (!_sideEffects.assistantMessageAdded) {
9863
+ _sideEffects.assistantMessageAdded = true;
9864
+ if (_sideEffects.assistantToolCallAddedForUpdater) {
9865
+ _sideEffects.assistantToolCallAddedForUpdater = false;
9866
+ }
9867
+ return [...currentConversation, message];
9868
+ }
9869
+ if (_sideEffects.assistantToolCallAddedForUpdater) {
9870
+ _sideEffects.assistantToolCallAddedForUpdater = false;
9871
+ return [...currentConversation, message];
9872
+ }
9873
+ return [...currentConversation.slice(0, -1), message];
9874
+ });
9875
+ }
9876
+ switch (chunk.type) {
9877
+ case "text-delta": {
9878
+ if (_sideEffects.assistantToolCallAddedForContent) {
9879
+ _sideEffects.assistantToolCallAddedForContent = false;
9880
+ _sideEffects.content = chunk.payload.text;
9881
+ } else {
9882
+ _sideEffects.content += chunk.payload.text;
9883
+ }
9884
+ updater();
9885
+ break;
9886
+ }
9887
+ case "tool-output": {
9888
+ if (chunk.payload.output?.type.startsWith("workflow-")) {
9889
+ handleWorkflowChunk({ workflowChunk: chunk.payload.output, setMessages, entityName: chunk.payload.toolName });
9890
+ }
9891
+ break;
9892
+ }
9893
+ case "tool-call": {
9894
+ setMessages((currentConversation) => {
9895
+ const lastMessage = currentConversation[currentConversation.length - 1];
9896
+ if (lastMessage && lastMessage.role === "assistant") {
9897
+ const updatedMessage = {
9898
+ ...lastMessage,
9899
+ content: Array.isArray(lastMessage.content) ? [
9900
+ ...lastMessage.content,
9901
+ {
9902
+ type: "tool-call",
9903
+ toolCallId: chunk.payload.toolCallId,
9904
+ toolName: chunk.payload.toolName,
9905
+ args: {
9906
+ ...chunk.payload.args,
9907
+ __mastraMetadata: {
9908
+ ...chunk.payload.args?.__mastraMetadata,
9909
+ isStreaming: true
9910
+ }
9911
+ }
9912
+ }
9913
+ ] : [
9914
+ ...typeof lastMessage.content === "string" ? [{ type: "text", text: lastMessage.content }] : [],
9915
+ {
9916
+ type: "tool-call",
9917
+ toolCallId: chunk.payload.toolCallId,
9918
+ toolName: chunk.payload.toolName,
9919
+ args: {
9920
+ ...chunk.payload.args,
9921
+ __mastraMetadata: {
9922
+ ...chunk.payload.args?.__mastraMetadata,
9923
+ isStreaming: true
9924
+ }
9925
+ }
9926
+ }
9927
+ ]
9928
+ };
9929
+ _sideEffects.assistantToolCallAddedForUpdater = true;
9930
+ _sideEffects.assistantToolCallAddedForContent = true;
9931
+ return [...currentConversation.slice(0, -1), updatedMessage];
9932
+ }
9933
+ const newMessage = {
9934
+ role: "assistant",
9935
+ content: [
9936
+ { type: "text", text: _sideEffects.content },
9937
+ {
9938
+ type: "tool-call",
9939
+ toolCallId: chunk.payload.toolCallId,
9940
+ toolName: chunk.payload.toolName,
9941
+ args: {
9942
+ ...chunk.payload.args,
9943
+ __mastraMetadata: { ...chunk.payload.args?.__mastraMetadata, isStreaming: true }
9944
+ }
9945
+ }
9946
+ ]
9947
+ };
9948
+ _sideEffects.assistantToolCallAddedForUpdater = true;
9949
+ _sideEffects.assistantToolCallAddedForContent = true;
9950
+ return [...currentConversation, newMessage];
9951
+ });
9952
+ _sideEffects.toolCallIdToName.current[chunk.payload.toolCallId] = chunk.payload.toolName;
9953
+ break;
9954
+ }
9955
+ case "tool-result": {
9956
+ setMessages((currentConversation) => {
9957
+ const lastMessage = currentConversation[currentConversation.length - 1];
9958
+ if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9959
+ const updatedContent = lastMessage.content.map((part) => {
9960
+ if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
9961
+ return {
9962
+ ...part,
9963
+ result: chunk.payload.result
9964
+ };
9965
+ }
9966
+ return part;
9967
+ });
9968
+ const updatedMessage = {
9969
+ ...lastMessage,
9970
+ content: updatedContent
9971
+ };
9972
+ return [...currentConversation.slice(0, -1), updatedMessage];
9973
+ }
9974
+ return currentConversation;
9975
+ });
9976
+ try {
9977
+ const toolName = _sideEffects.toolCallIdToName.current[chunk.payload.toolCallId];
9978
+ if (toolName === "updateWorkingMemory" && chunk.payload.result?.success) {
9979
+ await refreshWorkingMemory?.();
9980
+ }
9981
+ } finally {
9982
+ delete _sideEffects.toolCallIdToName.current[chunk.payload.toolCallId];
9983
+ }
9984
+ break;
9985
+ }
9986
+ case "error": {
9987
+ if (typeof chunk.payload.error === "string") {
9988
+ throw new Error(chunk.payload.error);
9989
+ }
9990
+ break;
9991
+ }
9992
+ case "finish": {
9993
+ handleFinishReason$1(chunk.payload.finishReason);
9994
+ break;
9995
+ }
9996
+ case "reasoning-delta": {
9997
+ setMessages((currentConversation) => {
9998
+ const lastMessage = currentConversation[currentConversation.length - 1];
9999
+ if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
10000
+ const updatedContent = lastMessage.content.map((part) => {
10001
+ if (typeof part === "object" && part.type === "reasoning") {
10002
+ return {
10003
+ ...part,
10004
+ text: part.text + chunk.payload.text
10005
+ };
10006
+ }
10007
+ return part;
10008
+ });
10009
+ const updatedMessage = {
10010
+ ...lastMessage,
10011
+ content: updatedContent
10012
+ };
10013
+ return [...currentConversation.slice(0, -1), updatedMessage];
10014
+ }
10015
+ const newMessage = {
10016
+ role: "assistant",
10017
+ content: [
10018
+ {
10019
+ type: "reasoning",
10020
+ text: chunk.payload.text
10021
+ },
10022
+ { type: "text", text: _sideEffects.content }
10023
+ ]
10024
+ };
10025
+ return [...currentConversation, newMessage];
10026
+ });
10027
+ break;
10028
+ }
10029
+ }
10030
+ };
10031
+ const handleFinishReason$1 = (finishReason) => {
10032
+ switch (finishReason) {
10033
+ case "tool-calls":
10034
+ throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
10035
+ }
10036
+ };
10037
+ const handleWorkflowChunk = ({ workflowChunk, setMessages, entityName }) => {
10038
+ reactDom.flushSync(() => {
10039
+ setMessages((currentConversation) => {
10040
+ const lastMessage = currentConversation[currentConversation.length - 1];
10041
+ const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
10042
+ const newMessage = {
10043
+ ...lastMessage,
10044
+ content: contentArray.map((part) => {
10045
+ if (part.type === "tool-call") {
10046
+ return {
10047
+ ...part,
10048
+ toolName: part?.entityName || entityName,
10049
+ args: {
10050
+ ...part.args,
10051
+ __mastraMetadata: {
10052
+ ...part.args?.__mastraMetadata,
10053
+ workflowFullState: mapWorkflowStreamChunkToWatchResult(
10054
+ part.args?.__mastraMetadata?.workflowFullState || {},
10055
+ workflowChunk
10056
+ ),
10057
+ isStreaming: true
10058
+ }
10059
+ }
10060
+ };
10061
+ }
10062
+ return part;
10063
+ })
10064
+ };
10065
+ return [...currentConversation.slice(0, -1), newMessage];
10066
+ });
10067
+ });
10068
+ };
10069
+ const handleAgentChunk = ({ agentChunk, setMessages, entityName }) => {
10070
+ switch (agentChunk.type) {
10071
+ case "tool-result": {
10072
+ setMessages((currentConversation) => {
10073
+ const lastMessage = currentConversation[currentConversation.length - 1];
10074
+ const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
10075
+ const newMessage = {
10076
+ ...lastMessage,
10077
+ content: contentArray.map((part) => {
10078
+ if (part.type === "tool-call") {
10079
+ const messages = part.args?.__mastraMetadata?.messages || [];
10080
+ const next = {
10081
+ ...part,
10082
+ toolName: part?.entityName || entityName,
10083
+ args: {
10084
+ ...part.args,
10085
+ __mastraMetadata: {
10086
+ ...part.args?.__mastraMetadata,
10087
+ isStreaming: true,
10088
+ messages: [
10089
+ ...messages.slice(0, -1),
10090
+ {
10091
+ ...messages[messages.length - 1],
10092
+ type: "tool",
10093
+ toolName: agentChunk.payload.toolName,
10094
+ args: agentChunk.payload.args,
10095
+ toolOutput: agentChunk.payload.result
10096
+ }
10097
+ ]
10098
+ }
10099
+ }
10100
+ };
10101
+ return next;
10102
+ }
10103
+ return part;
10104
+ })
10105
+ };
10106
+ return [...currentConversation.slice(0, -1), newMessage];
10107
+ });
10108
+ break;
10109
+ }
10110
+ case "tool-call": {
10111
+ setMessages((currentConversation) => {
10112
+ const lastMessage = currentConversation[currentConversation.length - 1];
10113
+ const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
10114
+ const newMessage = {
10115
+ ...lastMessage,
10116
+ content: contentArray.map((part) => {
10117
+ if (part.type === "tool-call") {
10118
+ const messages = part.args?.__mastraMetadata?.messages || [];
10119
+ const next = {
10120
+ ...part,
10121
+ toolName: part?.entityName || entityName,
10122
+ args: {
10123
+ ...part.args,
10124
+ __mastraMetadata: {
10125
+ ...part.args?.__mastraMetadata,
10126
+ isStreaming: true,
10127
+ messages: [
10128
+ ...messages,
10129
+ {
10130
+ type: "tool",
10131
+ toolCallId: agentChunk.payload.toolCallId,
10132
+ toolName: agentChunk.payload.toolName,
10133
+ args: {
10134
+ ...agentChunk.payload.args,
10135
+ __mastraMetadata: {
10136
+ ...agentChunk.payload.args?.__mastraMetadata,
10137
+ isStreaming: true
10138
+ }
10139
+ }
10140
+ }
10141
+ ]
10142
+ }
10143
+ }
10144
+ };
10145
+ return next;
10146
+ }
10147
+ return part;
10148
+ })
10149
+ };
10150
+ return [...currentConversation.slice(0, -1), newMessage];
10151
+ });
10152
+ break;
10153
+ }
10154
+ case "text-delta": {
10155
+ setMessages((currentConversation) => {
10156
+ const lastMessage = currentConversation[currentConversation.length - 1];
10157
+ const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
10158
+ const newMessage = {
10159
+ ...lastMessage,
10160
+ content: contentArray.map((part) => {
10161
+ if (part.type === "tool-call") {
10162
+ const messages = part.args?.__mastraMetadata?.messages || [];
10163
+ const lastMastraMessage = messages[messages.length - 1];
10164
+ const nextMessages = lastMastraMessage?.type === "text" ? [
10165
+ ...messages.slice(0, -1),
10166
+ { type: "text", content: (lastMastraMessage?.content || "") + agentChunk.payload.text }
10167
+ ] : [...messages, { type: "text", content: agentChunk.payload.text }];
10168
+ return {
10169
+ ...part,
10170
+ toolName: part?.entityName || entityName,
10171
+ args: {
10172
+ ...part.args,
10173
+ __mastraMetadata: {
10174
+ ...part.args?.__mastraMetadata,
10175
+ isStreaming: true,
10176
+ messages: nextMessages
10177
+ }
10178
+ }
10179
+ };
10180
+ }
10181
+ return part;
10182
+ })
10183
+ };
10184
+ return [...currentConversation.slice(0, -1), newMessage];
10185
+ });
10186
+ break;
10187
+ }
10188
+ case "tool-output": {
10189
+ reactDom.flushSync(() => {
10190
+ setMessages((currentConversation) => {
10191
+ if (!agentChunk.payload.output.type.startsWith("workflow-")) return currentConversation;
10192
+ const lastMessage = currentConversation[currentConversation.length - 1];
10193
+ const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
10194
+ const newMessage = {
10195
+ ...lastMessage,
10196
+ content: contentArray.map((part) => {
10197
+ if (part.type === "tool-call") {
10198
+ const messages = part.args?.__mastraMetadata?.messages || [];
10199
+ const lastMastraMessage = messages[messages.length - 1];
10200
+ const nextMessages = lastMastraMessage?.type === "tool" ? [
10201
+ ...messages.slice(0, -1),
10202
+ {
10203
+ ...lastMastraMessage,
10204
+ args: {
10205
+ ...agentChunk.payload.args,
10206
+ __mastraMetadata: {
10207
+ ...agentChunk.payload.args?.__mastraMetadata,
10208
+ workflowFullState: mapWorkflowStreamChunkToWatchResult(
10209
+ lastMastraMessage.args?.__mastraMetadata?.workflowFullState || {},
10210
+ agentChunk.payload.output
10211
+ ),
10212
+ isStreaming: true
10213
+ }
10214
+ }
10215
+ }
10216
+ ] : messages;
10217
+ return {
10218
+ ...part,
10219
+ toolName: part?.entityName || entityName,
10220
+ args: {
10221
+ ...part.args,
10222
+ __mastraMetadata: {
10223
+ ...part.args?.__mastraMetadata,
10224
+ isStreaming: true,
10225
+ messages: nextMessages
10226
+ }
10227
+ }
10228
+ };
10229
+ }
10230
+ return part;
10231
+ })
10232
+ };
10233
+ return [...currentConversation.slice(0, -1), newMessage];
10234
+ });
10235
+ });
10236
+ break;
10237
+ }
10238
+ }
10239
+ };
10240
+ const createRootToolAssistantMessage = ({
10241
+ chunk,
10242
+ entityName,
10243
+ setMessages,
10244
+ runId,
10245
+ _sideEffects,
10246
+ from,
10247
+ networkMetadata
10248
+ }) => {
10249
+ setMessages((currentConversation) => {
10250
+ if (!entityName || !runId) return currentConversation;
10251
+ const newMessage = {
10252
+ role: "assistant",
10253
+ content: [
10254
+ { type: "text", text: _sideEffects.content },
10255
+ {
10256
+ type: "tool-call",
10257
+ toolCallId: runId,
10258
+ toolName: entityName,
10259
+ args: {
10260
+ ...chunk?.payload?.args,
10261
+ __mastraMetadata: {
10262
+ from,
10263
+ networkMetadata,
10264
+ ...chunk.payload.args?.__mastraMetadata,
10265
+ isStreaming: true
10266
+ }
10267
+ }
10268
+ }
10269
+ ]
10270
+ };
10271
+ _sideEffects.assistantToolCallAddedForUpdater = true;
10272
+ _sideEffects.assistantToolCallAddedForContent = true;
10273
+ return [...currentConversation, newMessage];
10274
+ });
10275
+ };
10276
+
10277
+ const convertMessage$2 = (message) => {
10278
+ return message;
10279
+ };
10280
+ const handleFinishReason = (finishReason) => {
10281
+ switch (finishReason) {
10282
+ case "tool-calls":
10283
+ throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
10284
+ }
10285
+ };
10286
+ const convertToAIAttachments = async (attachments) => {
10287
+ const promises = (attachments ?? []).filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
10288
+ const isFileFromURL = attachment.name.startsWith("https://");
10289
+ if (attachment.type === "document") {
10290
+ if (attachment.contentType === "application/pdf") {
10291
+ const pdfText = attachment.content?.[0]?.text || "";
9622
10292
  return {
9623
10293
  role: "user",
9624
10294
  content: [
@@ -9678,7 +10348,7 @@ function MastraRuntimeProvider({
9678
10348
  instructions,
9679
10349
  chatWithGenerate,
9680
10350
  chatWithGenerateVNext,
9681
- chatWithStreamVNext,
10351
+ chatWithNetwork,
9682
10352
  providerOptions
9683
10353
  } = settings?.modelSettings ?? {};
9684
10354
  const toolCallIdToName = React.useRef({});
@@ -9691,6 +10361,14 @@ function MastraRuntimeProvider({
9691
10361
  if (messages.length === 0 || currentThreadId !== threadId || hasNewInitialMessages && currentThreadId === threadId) {
9692
10362
  if (initialMessages && threadId && memory) {
9693
10363
  const convertedMessages = initialMessages?.map((message) => {
10364
+ let content;
10365
+ try {
10366
+ content = JSON.parse(message.content);
10367
+ if (content.isNetwork) {
10368
+ return handleNetworkMessageFromMemory(content);
10369
+ }
10370
+ } catch (e) {
10371
+ }
9694
10372
  const attachmentsAsContentParts = (message.experimental_attachments || []).map((image) => ({
9695
10373
  type: image.contentType.startsWith(`image/`) ? "image" : image.contentType.startsWith(`audio/`) ? "audio" : "file",
9696
10374
  mimeType: image.contentType,
@@ -9837,63 +10515,15 @@ function MastraRuntimeProvider({
9837
10515
  }
9838
10516
  };
9839
10517
  if (modelVersion === "v2") {
9840
- if (chatWithGenerateVNext) {
9841
- const response = await agent.generateVNext({
10518
+ if (chatWithNetwork) {
10519
+ const response = await agent.network({
9842
10520
  messages: [
9843
10521
  {
9844
10522
  role: "user",
9845
10523
  content: input
9846
- },
9847
- ...attachments
9848
- ],
9849
- runId: agentId,
9850
- modelSettings: {
9851
- frequencyPenalty,
9852
- presencePenalty,
9853
- maxRetries,
9854
- temperature,
9855
- topK,
9856
- topP,
9857
- maxOutputTokens: maxTokens
9858
- },
9859
- providerOptions,
9860
- instructions,
9861
- runtimeContext: runtimeContextInstance,
9862
- ...memory ? { threadId, resourceId: agentId } : {}
9863
- });
9864
- handleGenerateResponse(response);
9865
- setIsRunning(false);
9866
- return;
9867
- } else {
9868
- let updater = function() {
9869
- setMessages((currentConversation) => {
9870
- const message2 = {
9871
- role: "assistant",
9872
- content: [{ type: "text", text: content }]
9873
- };
9874
- if (!assistantMessageAdded) {
9875
- assistantMessageAdded = true;
9876
- if (assistantToolCallAddedForUpdater) {
9877
- assistantToolCallAddedForUpdater = false;
9878
- }
9879
- return [...currentConversation, message2];
9880
10524
  }
9881
- if (assistantToolCallAddedForUpdater) {
9882
- assistantToolCallAddedForUpdater = false;
9883
- return [...currentConversation, message2];
9884
- }
9885
- return [...currentConversation.slice(0, -1), message2];
9886
- });
9887
- };
9888
- const response = await agent.streamVNext({
9889
- messages: [
9890
- {
9891
- role: "user",
9892
- content: input
9893
- },
9894
- ...attachments
9895
10525
  ],
9896
- runId: agentId,
10526
+ maxSteps,
9897
10527
  modelSettings: {
9898
10528
  frequencyPenalty,
9899
10529
  presencePenalty,
@@ -9903,203 +10533,159 @@ function MastraRuntimeProvider({
9903
10533
  topK,
9904
10534
  topP
9905
10535
  },
9906
- instructions,
10536
+ runId: agentId,
9907
10537
  runtimeContext: runtimeContextInstance,
9908
- ...memory ? { threadId, resourceId: agentId } : {},
9909
- providerOptions
10538
+ ...memory ? { thread: threadId, resourceId: agentId } : {}
9910
10539
  });
9911
- if (!response.body) {
9912
- throw new Error("No response body");
9913
- }
9914
- let content = "";
9915
- let assistantMessageAdded = false;
9916
- let assistantToolCallAddedForUpdater = false;
9917
- let assistantToolCallAddedForContent = false;
10540
+ const _sideEffects = {
10541
+ assistantMessageAdded: false,
10542
+ assistantToolCallAddedForUpdater: false,
10543
+ assistantToolCallAddedForContent: false,
10544
+ content: "",
10545
+ toolCallIdToName
10546
+ };
10547
+ let currentEntityId;
9918
10548
  await response.processDataStream({
9919
10549
  onChunk: async (chunk) => {
9920
- switch (chunk.type) {
9921
- case "text-delta": {
9922
- if (assistantToolCallAddedForContent) {
9923
- assistantToolCallAddedForContent = false;
9924
- content = chunk.payload.text;
9925
- } else {
9926
- content += chunk.payload.text;
9927
- }
9928
- updater();
9929
- break;
9930
- }
9931
- case "tool-output": {
9932
- if (!chunk.payload.output?.type.startsWith("workflow-")) return;
9933
- reactDom.flushSync(() => {
9934
- setMessages((currentConversation) => {
9935
- const lastMessage = currentConversation[currentConversation.length - 1];
9936
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9937
- const newMessage = {
9938
- ...lastMessage,
9939
- content: contentArray.map((part) => {
9940
- if (part.type === "tool-call") {
9941
- return {
9942
- ...part,
9943
- ...chunk.payload,
9944
- args: {
9945
- ...part.args,
9946
- __mastraMetadata: {
9947
- ...part.args?.__mastraMetadata,
9948
- partialChunk: chunk?.payload?.output,
9949
- isStreaming: true
9950
- }
9951
- }
9952
- };
9953
- }
9954
- return part;
9955
- })
9956
- };
9957
- return [...currentConversation.slice(0, -1), newMessage];
9958
- });
9959
- });
9960
- break;
9961
- }
9962
- case "tool-call": {
9963
- setMessages((currentConversation) => {
9964
- const lastMessage = currentConversation[currentConversation.length - 1];
9965
- if (lastMessage && lastMessage.role === "assistant") {
9966
- const updatedMessage = {
9967
- ...lastMessage,
9968
- content: Array.isArray(lastMessage.content) ? [
9969
- ...lastMessage.content,
9970
- {
9971
- type: "tool-call",
9972
- toolCallId: chunk.payload.toolCallId,
9973
- toolName: chunk.payload.toolName,
9974
- args: {
9975
- ...chunk.payload.args,
9976
- __mastraMetadata: {
9977
- ...chunk.payload.args?.__mastraMetadata,
9978
- isStreaming: true
9979
- }
9980
- }
9981
- }
9982
- ] : [
9983
- ...typeof lastMessage.content === "string" ? [{ type: "text", text: lastMessage.content }] : [],
9984
- {
9985
- type: "tool-call",
9986
- toolCallId: chunk.payload.toolCallId,
9987
- toolName: chunk.payload.toolName,
9988
- args: {
9989
- ...chunk.payload.args,
9990
- __mastraMetadata: {
9991
- ...chunk.payload.args?.__mastraMetadata,
9992
- isStreaming: true
9993
- }
9994
- }
9995
- }
9996
- ]
9997
- };
9998
- assistantToolCallAddedForUpdater = true;
9999
- assistantToolCallAddedForContent = true;
10000
- return [...currentConversation.slice(0, -1), updatedMessage];
10001
- }
10002
- const newMessage = {
10003
- role: "assistant",
10004
- content: [
10005
- { type: "text", text: content },
10006
- {
10007
- type: "tool-call",
10008
- toolCallId: chunk.payload.toolCallId,
10009
- toolName: chunk.payload.toolName,
10010
- args: {
10011
- ...chunk.payload.args,
10012
- __mastraMetadata: { ...chunk.payload.args?.__mastraMetadata, isStreaming: true }
10550
+ if (chunk.type.startsWith("agent-execution-event-")) {
10551
+ const agentChunk = chunk.payload;
10552
+ if (!currentEntityId) return;
10553
+ await handleAgentChunk({ agentChunk, setMessages, entityName: currentEntityId });
10554
+ } else if (chunk.type === "tool-execution-start") {
10555
+ await handleStreamChunk({
10556
+ chunk: {
10557
+ ...chunk,
10558
+ type: "tool-call",
10559
+ payload: {
10560
+ ...chunk?.payload,
10561
+ toolCallId: chunk?.payload?.args?.toolCallId,
10562
+ toolName: chunk?.payload?.args?.toolName,
10563
+ args: {
10564
+ ...chunk?.payload?.args?.args,
10565
+ __mastraMetadata: {
10566
+ ...chunk?.payload?.args?.__mastraMetadata,
10567
+ networkMetadata: {
10568
+ selectionReason: chunk?.payload?.args?.selectionReason || "",
10569
+ input: chunk?.payload?.args?.args
10013
10570
  }
10014
10571
  }
10015
- ]
10016
- };
10017
- assistantToolCallAddedForUpdater = true;
10018
- assistantToolCallAddedForContent = true;
10019
- return [...currentConversation, newMessage];
10020
- });
10021
- toolCallIdToName.current[chunk.payload.toolCallId] = chunk.payload.toolName;
10022
- break;
10023
- }
10024
- case "tool-result": {
10025
- setMessages((currentConversation) => {
10026
- const lastMessage = currentConversation[currentConversation.length - 1];
10027
- if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
10028
- const updatedContent = lastMessage.content.map((part) => {
10029
- if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
10030
- return {
10031
- ...part,
10032
- result: chunk.payload.result
10033
- };
10034
- }
10035
- return part;
10036
- });
10037
- const updatedMessage = {
10038
- ...lastMessage,
10039
- content: updatedContent
10040
- };
10041
- return [...currentConversation.slice(0, -1), updatedMessage];
10042
- }
10043
- return currentConversation;
10044
- });
10045
- try {
10046
- const toolName = toolCallIdToName.current[chunk.payload.toolCallId];
10047
- if (toolName === "updateWorkingMemory" && chunk.payload.result?.success) {
10048
- await refreshWorkingMemory?.();
10572
+ }
10049
10573
  }
10050
- } finally {
10051
- delete toolCallIdToName.current[chunk.payload.toolCallId];
10052
- }
10053
- break;
10054
- }
10055
- case "error": {
10056
- if (typeof chunk.payload.error === "string") {
10057
- throw new Error(chunk.payload.error);
10574
+ },
10575
+ setMessages,
10576
+ refreshWorkingMemory,
10577
+ _sideEffects
10578
+ });
10579
+ } else if (chunk.type === "tool-execution-end") {
10580
+ await handleStreamChunk({
10581
+ chunk: { ...chunk, type: "tool-result" },
10582
+ setMessages,
10583
+ refreshWorkingMemory,
10584
+ _sideEffects
10585
+ });
10586
+ } else if (chunk.type.startsWith("workflow-execution-event-")) {
10587
+ const workflowChunk = chunk.payload;
10588
+ if (!currentEntityId) return;
10589
+ await handleWorkflowChunk({ workflowChunk, setMessages, entityName: currentEntityId });
10590
+ } else if (chunk.type === "workflow-execution-start" || chunk.type === "agent-execution-start") {
10591
+ currentEntityId = chunk.payload?.args?.resourceId;
10592
+ const runId = chunk.payload.runId;
10593
+ if (!currentEntityId || !runId) return;
10594
+ createRootToolAssistantMessage({
10595
+ entityName: currentEntityId,
10596
+ setMessages,
10597
+ runId,
10598
+ _sideEffects,
10599
+ chunk,
10600
+ from: chunk.type === "agent-execution-start" ? "AGENT" : "WORKFLOW",
10601
+ networkMetadata: {
10602
+ selectionReason: chunk?.payload?.args?.selectionReason || "",
10603
+ input: chunk?.payload?.args?.prompt
10058
10604
  }
10059
- break;
10060
- }
10061
- case "finish": {
10062
- handleFinishReason(chunk.payload.finishReason);
10063
- break;
10064
- }
10065
- case "reasoning-delta": {
10066
- setMessages((currentConversation) => {
10067
- const lastMessage = currentConversation[currentConversation.length - 1];
10068
- if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
10069
- const updatedContent = lastMessage.content.map((part) => {
10070
- if (typeof part === "object" && part.type === "reasoning") {
10071
- return {
10072
- ...part,
10073
- text: part.text + chunk.payload.text
10074
- };
10075
- }
10076
- return part;
10077
- });
10078
- const updatedMessage = {
10079
- ...lastMessage,
10080
- content: updatedContent
10081
- };
10082
- return [...currentConversation.slice(0, -1), updatedMessage];
10083
- }
10084
- const newMessage = {
10085
- role: "assistant",
10086
- content: [
10087
- {
10088
- type: "reasoning",
10089
- text: chunk.payload.text
10090
- },
10091
- { type: "text", text: content }
10092
- ]
10093
- };
10094
- return [...currentConversation, newMessage];
10095
- });
10096
- break;
10097
- }
10605
+ });
10606
+ _sideEffects.toolCallIdToName.current[runId] = currentEntityId;
10607
+ } else if (chunk.type === "network-execution-event-step-finish") {
10608
+ setMessages((currentConversation) => {
10609
+ return [
10610
+ ...currentConversation,
10611
+ { role: "assistant", content: [{ type: "text", text: chunk?.payload?.result || "" }] }
10612
+ ];
10613
+ });
10614
+ } else {
10615
+ await handleStreamChunk({ chunk, setMessages, refreshWorkingMemory, _sideEffects });
10098
10616
  }
10099
10617
  }
10100
10618
  });
10101
- setIsRunning(false);
10102
- return;
10619
+ } else {
10620
+ if (chatWithGenerateVNext) {
10621
+ const response = await agent.generateVNext({
10622
+ messages: [
10623
+ {
10624
+ role: "user",
10625
+ content: input
10626
+ },
10627
+ ...attachments
10628
+ ],
10629
+ runId: agentId,
10630
+ modelSettings: {
10631
+ frequencyPenalty,
10632
+ presencePenalty,
10633
+ maxRetries,
10634
+ temperature,
10635
+ topK,
10636
+ topP,
10637
+ maxOutputTokens: maxTokens
10638
+ },
10639
+ providerOptions,
10640
+ instructions,
10641
+ runtimeContext: runtimeContextInstance,
10642
+ ...memory ? { threadId, resourceId: agentId } : {}
10643
+ });
10644
+ handleGenerateResponse(response);
10645
+ setIsRunning(false);
10646
+ return;
10647
+ } else {
10648
+ const response = await agent.streamVNext({
10649
+ messages: [
10650
+ {
10651
+ role: "user",
10652
+ content: input
10653
+ },
10654
+ ...attachments
10655
+ ],
10656
+ runId: agentId,
10657
+ modelSettings: {
10658
+ frequencyPenalty,
10659
+ presencePenalty,
10660
+ maxRetries,
10661
+ maxOutputTokens: maxTokens,
10662
+ temperature,
10663
+ topK,
10664
+ topP
10665
+ },
10666
+ instructions,
10667
+ runtimeContext: runtimeContextInstance,
10668
+ ...memory ? { threadId, resourceId: agentId } : {},
10669
+ providerOptions
10670
+ });
10671
+ if (!response.body) {
10672
+ throw new Error("No response body");
10673
+ }
10674
+ const _sideEffects = {
10675
+ assistantMessageAdded: false,
10676
+ assistantToolCallAddedForUpdater: false,
10677
+ assistantToolCallAddedForContent: false,
10678
+ content: "",
10679
+ toolCallIdToName
10680
+ };
10681
+ await response.processDataStream({
10682
+ onChunk: async (chunk) => {
10683
+ await handleStreamChunk({ chunk, setMessages, refreshWorkingMemory, _sideEffects });
10684
+ }
10685
+ });
10686
+ setIsRunning(false);
10687
+ return;
10688
+ }
10103
10689
  }
10104
10690
  } else {
10105
10691
  if (chatWithGenerate) {
@@ -10482,7 +11068,6 @@ const AgentChat = ({
10482
11068
  initialMessages,
10483
11069
  memory,
10484
11070
  refreshThreadList,
10485
- onInputChange,
10486
11071
  modelVersion
10487
11072
  }) => {
10488
11073
  const { settings } = useAgentSettings();
@@ -10499,7 +11084,7 @@ const AgentChat = ({
10499
11084
  refreshThreadList,
10500
11085
  settings,
10501
11086
  runtimeContext,
10502
- children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { agentName: agentName ?? "", hasMemory: memory, onInputChange, agentId })
11087
+ children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { agentName: agentName ?? "", hasMemory: memory, agentId })
10503
11088
  }
10504
11089
  );
10505
11090
  };
@@ -11106,7 +11691,11 @@ const AgentSettings = ({ modelVersion }) => {
11106
11691
  const { settings, setSettings, resetAll } = useAgentSettings();
11107
11692
  let radioValue;
11108
11693
  if (modelVersion === "v2") {
11109
- radioValue = settings?.modelSettings?.chatWithGenerateVNext ? "generateVNext" : "streamVNext";
11694
+ if (settings?.modelSettings?.chatWithNetwork) {
11695
+ radioValue = "network";
11696
+ } else {
11697
+ radioValue = settings?.modelSettings?.chatWithGenerateVNext ? "generateVNext" : "streamVNext";
11698
+ }
11110
11699
  } else {
11111
11700
  radioValue = settings?.modelSettings?.chatWithGenerate ? "generate" : "stream";
11112
11701
  }
@@ -11123,7 +11712,8 @@ const AgentSettings = ({ modelVersion }) => {
11123
11712
  ...settings?.modelSettings,
11124
11713
  chatWithGenerate: value === "generate",
11125
11714
  chatWithGenerateVNext: value === "generateVNext",
11126
- chatWithStreamVNext: value === "streamVNext"
11715
+ chatWithStreamVNext: value === "streamVNext",
11716
+ chatWithNetwork: value === "network"
11127
11717
  }
11128
11718
  }),
11129
11719
  className: "flex flex-row gap-4",
@@ -11143,6 +11733,10 @@ const AgentSettings = ({ modelVersion }) => {
11143
11733
  modelVersion === "v2" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11144
11734
  /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "streamVNext", id: "streamVNext", className: "text-icon6" }),
11145
11735
  /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-icon6 text-ui-md", htmlFor: "streamVNext", children: "Stream vNext" })
11736
+ ] }),
11737
+ modelVersion === "v2" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11738
+ /* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: "network", id: "network", className: "text-icon6" }),
11739
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-icon6 text-ui-md", htmlFor: "network", children: "Network" })
11146
11740
  ] })
11147
11741
  ]
11148
11742
  }
@@ -12276,10 +12870,18 @@ const AgentMetadataModelSwitcher = ({
12276
12870
  ] }) });
12277
12871
  };
12278
12872
 
12873
+ const AgentMetadataNetworkList = ({ agents, computeAgentLink }) => {
12874
+ const { Link } = useLinkComponent();
12875
+ if (agents.length === 0) {
12876
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListEmpty, { children: "No tools" });
12877
+ }
12878
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataList, { children: agents.map((agent) => /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: computeAgentLink(agent), children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { variant: "success", icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}), children: agent.name }) }) }, agent.id)) });
12879
+ };
12279
12880
  const AgentMetadata = ({
12280
12881
  agent,
12281
12882
  promptSlot,
12282
12883
  hasMemoryEnabled,
12884
+ computeAgentLink,
12283
12885
  computeToolLink,
12284
12886
  computeWorkflowLink,
12285
12887
  updateModel,
@@ -12287,6 +12889,8 @@ const AgentMetadata = ({
12287
12889
  }) => {
12288
12890
  const [isEditingModel, setIsEditingModel] = React.useState(false);
12289
12891
  const providerIcon = providerMapToIcon[agent.provider || "openai.chat"];
12892
+ const networkAgentsMap = agent.agents ?? {};
12893
+ const networkAgents = Object.values(networkAgentsMap);
12290
12894
  const agentTools = agent.tools ?? {};
12291
12895
  const tools = Object.keys(agentTools).map((key) => agentTools[key]);
12292
12896
  const agentWorkflows = agent.workflows ?? {};
@@ -12303,7 +12907,16 @@ const AgentMetadata = ({
12303
12907
  }
12304
12908
  ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
12305
12909
  /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: providerIcon, className: "font-medium", children: agent.modelId || "N/A" }),
12306
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setIsEditingModel(true), className: "text-icon3 hover:text-icon6", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EditIcon, {}) }) })
12910
+ /* @__PURE__ */ jsxRuntime.jsx(
12911
+ "button",
12912
+ {
12913
+ title: "Edit model",
12914
+ type: "button",
12915
+ onClick: () => setIsEditingModel(true),
12916
+ className: "text-icon3 hover:text-icon6",
12917
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EditIcon, {}) })
12918
+ }
12919
+ )
12307
12920
  ] }) }),
12308
12921
  /* @__PURE__ */ jsxRuntime.jsx(
12309
12922
  AgentMetadataSection,
@@ -12316,6 +12929,17 @@ const AgentMetadata = ({
12316
12929
  children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(MemoryIcon, {}), variant: hasMemoryEnabled ? "success" : "error", className: "font-medium", children: hasMemoryEnabled ? "On" : "Off" })
12317
12930
  }
12318
12931
  ),
12932
+ networkAgents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
12933
+ AgentMetadataSection,
12934
+ {
12935
+ title: "Agents",
12936
+ hint: {
12937
+ link: "https://mastra.ai/en/docs/agents/overview",
12938
+ title: "Agents documentation"
12939
+ },
12940
+ children: /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataNetworkList, { agents: networkAgents, computeAgentLink })
12941
+ }
12942
+ ),
12319
12943
  /* @__PURE__ */ jsxRuntime.jsx(
12320
12944
  AgentMetadataSection,
12321
12945
  {
@@ -15783,42 +16407,31 @@ function TemplateInfo({
15783
16407
  }) {
15784
16408
  const branchName = templateSlug ? `feat/install-template-${templateSlug}` : "feat/install-template-[slug]";
15785
16409
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15786
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] lg:min-h-[4rem] items-center "), children: [
15787
- /* @__PURE__ */ jsxRuntime.jsxs(
15788
- "div",
15789
- {
15790
- className: cn(
15791
- "text-[1.5rem] flex items-center gap-[0.75rem] ",
15792
- "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
16410
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid mt-[2rem] items-center"), children: /* @__PURE__ */ jsxRuntime.jsxs(
16411
+ "div",
16412
+ {
16413
+ className: cn(
16414
+ "text-[1.5rem] flex items-center gap-[0.75rem]",
16415
+ "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
16416
+ {
16417
+ "[&>svg]:opacity-20": isLoading
16418
+ }
16419
+ ),
16420
+ children: [
16421
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, {}),
16422
+ /* @__PURE__ */ jsxRuntime.jsx(
16423
+ "h2",
15793
16424
  {
15794
- "[&>svg]:opacity-20": isLoading
16425
+ className: cn({
16426
+ "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
16427
+ }),
16428
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : title
15795
16429
  }
15796
- ),
15797
- children: [
15798
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, {}),
15799
- /* @__PURE__ */ jsxRuntime.jsx(
15800
- "h2",
15801
- {
15802
- className: cn({
15803
- "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
15804
- }),
15805
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : title
15806
- }
15807
- )
15808
- ]
15809
- }
15810
- ),
15811
- /* @__PURE__ */ jsxRuntime.jsx(
15812
- "div",
15813
- {
15814
- className: "w-full h-full bg-cover bg-center transition-scale duration-150 rounded-lg overflow-hidden min-h-[2rem] mt-[2rem] lg:mt-0",
15815
- style: {
15816
- backgroundImage: `url(${imageURL})`
15817
- }
15818
- }
15819
- )
15820
- ] }),
15821
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] ", children: [
16430
+ )
16431
+ ]
16432
+ }
16433
+ ) }),
16434
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] ", children: [
15822
16435
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid", children: [
15823
16436
  /* @__PURE__ */ jsxRuntime.jsx(
15824
16437
  "p",
@@ -18425,6 +19038,7 @@ exports.AgentMetadata = AgentMetadata;
18425
19038
  exports.AgentMetadataList = AgentMetadataList;
18426
19039
  exports.AgentMetadataListEmpty = AgentMetadataListEmpty;
18427
19040
  exports.AgentMetadataListItem = AgentMetadataListItem;
19041
+ exports.AgentMetadataNetworkList = AgentMetadataNetworkList;
18428
19042
  exports.AgentMetadataPrompt = AgentMetadataPrompt;
18429
19043
  exports.AgentMetadataScorerList = AgentMetadataScorerList;
18430
19044
  exports.AgentMetadataSection = AgentMetadataSection;
@@ -18571,6 +19185,7 @@ exports.TextareaField = TextareaField;
18571
19185
  exports.Th = Th;
18572
19186
  exports.Thead = Thead;
18573
19187
  exports.ThreadDeleteButton = ThreadDeleteButton;
19188
+ exports.ThreadInputProvider = ThreadInputProvider;
18574
19189
  exports.ThreadItem = ThreadItem;
18575
19190
  exports.ThreadLink = ThreadLink;
18576
19191
  exports.ThreadList = ThreadList;
@@ -18631,6 +19246,7 @@ exports.useScorers = useScorers;
18631
19246
  exports.useScoresByEntityId = useScoresByEntityId;
18632
19247
  exports.useScoresByScorerId = useScoresByScorerId;
18633
19248
  exports.useSpeechRecognition = useSpeechRecognition;
19249
+ exports.useThreadInput = useThreadInput;
18634
19250
  exports.useWorkingMemory = useWorkingMemory;
18635
19251
  Object.keys(reactQuery).forEach(k => {
18636
19252
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {