@mastra/playground-ui 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/dist/index.cjs.js +2300 -811
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +2293 -813
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/src/domains/agents/components/agent-cms-form-shell.d.ts +2 -1
  7. package/dist/src/domains/agents/components/agent-cms-layout/agent-cms-layout.d.ts +2 -1
  8. package/dist/src/domains/agents/components/agent-cms-pages/index.d.ts +1 -0
  9. package/dist/src/domains/agents/components/agent-cms-pages/skill-edit-dialog.d.ts +8 -0
  10. package/dist/src/domains/agents/components/agent-cms-pages/skill-file-tree.d.ts +15 -0
  11. package/dist/src/domains/agents/components/agent-cms-pages/skill-folder.d.ts +14 -0
  12. package/dist/src/domains/agents/components/agent-cms-pages/skills-page.d.ts +1 -0
  13. package/dist/src/domains/agents/components/agent-cms-sidebar/use-sidebar-descriptions.d.ts +4 -0
  14. package/dist/src/domains/agents/components/agent-edit-page/use-agent-edit-form.d.ts +32 -0
  15. package/dist/src/domains/agents/components/agent-edit-page/utils/form-validation.d.ts +43 -0
  16. package/dist/src/domains/agents/components/agent-version-panel.d.ts +7 -0
  17. package/dist/src/domains/agents/hooks/use-agent-cms-form.d.ts +33 -0
  18. package/dist/src/domains/agents/hooks/use-agent-skills.d.ts +12 -0
  19. package/dist/src/domains/agents/hooks/use-agent-workspace.d.ts +13 -0
  20. package/dist/src/domains/agents/hooks/use-create-skill.d.ts +10 -0
  21. package/dist/src/domains/agents/hooks/use-stored-skills.d.ts +1 -0
  22. package/dist/src/domains/agents/index.d.ts +3 -0
  23. package/dist/src/domains/agents/utils/agent-form-mappers.d.ts +6 -1
  24. package/dist/src/domains/agents/utils/compute-agent-initial-values.d.ts +3 -0
  25. package/dist/src/domains/datasets/components/dataset-combobox.d.ts +11 -0
  26. package/dist/src/domains/datasets/hooks/use-dataset-item-versions.d.ts +1 -1
  27. package/dist/src/domains/datasets/index.d.ts +2 -0
  28. package/dist/src/domains/experiments/hooks/use-experiment-trace.d.ts +1 -1
  29. package/dist/src/domains/mcps/components/mcp-client-create/mcp-client-create-content.d.ts +7 -1
  30. package/dist/src/domains/mcps/components/mcp-client-create/mcp-client-form-sidebar.d.ts +2 -1
  31. package/dist/src/domains/mcps/components/mcp-client-create/mcp-client-tool-preview.d.ts +6 -1
  32. package/dist/src/ds/components/Breadcrumb/Breadcrumb.d.ts +1 -1
  33. package/dist/src/ds/components/CodeDiff/code-diff.d.ts +5 -0
  34. package/dist/src/ds/components/CodeDiff/code-diff.stories.d.ts +9 -0
  35. package/dist/src/ds/components/CodeDiff/index.d.ts +2 -0
  36. package/dist/src/ds/components/FormFields/select-field.d.ts +1 -0
  37. package/dist/src/ds/components/Tree/index.d.ts +1 -0
  38. package/dist/src/ds/components/Tree/tree-context.d.ts +15 -0
  39. package/dist/src/ds/components/Tree/tree-file.d.ts +7 -0
  40. package/dist/src/ds/components/Tree/tree-folder-content.d.ts +6 -0
  41. package/dist/src/ds/components/Tree/tree-folder-trigger.d.ts +7 -0
  42. package/dist/src/ds/components/Tree/tree-folder.d.ts +9 -0
  43. package/dist/src/ds/components/Tree/tree-icon.d.ts +6 -0
  44. package/dist/src/ds/components/Tree/tree-input.d.ts +11 -0
  45. package/dist/src/ds/components/Tree/tree-label.d.ts +6 -0
  46. package/dist/src/ds/components/Tree/tree-root.d.ts +8 -0
  47. package/dist/src/ds/components/Tree/tree.d.ts +9 -0
  48. package/dist/src/ds/components/Tree/tree.stories.d.ts +10 -0
  49. package/dist/src/index.d.ts +2 -0
  50. package/package.json +14 -13
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useAssistantState, useAuiState, useMessage, MessagePrimitive, ActionBarPrimitive, useComposerRuntime, useAttachment, ComposerPrimitive, AttachmentPrimitive, useComposer, ThreadPrimitive, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechSynthesisAdapter, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
3
- import { CheckIcon as CheckIcon$1, CopyIcon, ShieldAlert, ChevronDown, ChevronRight, RefreshCw, Tag, Wand2, InfoIcon as InfoIcon$1, AlertCircle, TriangleAlert, ChevronUpIcon, CheckCircleIcon, X, CircleCheck, CircleX, CircleAlert, Info, Share2, Check, TerminalSquare, FolderTree, HardDrive, Clock as Clock$1, PlayCircle, Workflow, Layers, List, CalendarClock, Timer, CornerDownRight, GitBranch, Repeat, Repeat1, Network, TriangleAlertIcon, SearchIcon, XIcon, CalendarIcon, CircleAlertIcon, Braces, ChevronDownIcon, Brackets, PlusIcon, TrashIcon, Plus, Loader2, Circle, EyeOffIcon, EyeIcon, PauseIcon, HourglassIcon, CircleDashed, Footprints, Minus, Maximize, AlertCircleIcon, StopCircle, CirclePause, Cpu, ChevronsUpDown, Search, ArrowRight, ArrowLeft, Brain, Unplug, XCircle, CloudCog, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, SaveIcon, Database, Code2, Type, ToggleLeft, Hash, Ban, ListX, ChevronsLeft, ChevronsRight, ChevronLeft, Text, TextSearch, EqualNot, Equal, Component, Trash2, Ruler, Trash, Link2, ExternalLink, MoveRight, Copy, BookOpen, ArrowLeftIcon, ArrowRightIcon, ChevronsRightIcon, AlignLeftIcon, AlignJustifyIcon, ArrowUpIcon, ArrowDownIcon, ChevronRightIcon, GaugeIcon, ChevronsLeftRightEllipsisIcon, CalculatorIcon, HashIcon, FileInputIcon, FileOutputIcon, ReceiptText, Save, RotateCcw, GripVertical, Folder, Pencil, CopyPlus, RefreshCcwIcon, Plug, LaptopMinimal, AlignLeft, Trash2Icon, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, AlertTriangleIcon, FrownIcon, CircleChevronUpIcon, CircleChevronDownIcon, FileIcon, ChevronsUpIcon, ChevronsDownIcon, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, CircleDashedIcon, ArrowRightToLineIcon, CoinsIcon, BracesIcon, CircleGaugeIcon, PanelTopIcon, DatabaseIcon, ListTreeIcon, PanelLeftIcon, Upload, FileJson, MoveRightIcon, History, ScaleIcon, Download, FolderPlus, FolderOutput, FileCodeIcon, Calendar1Icon, HistoryIcon, TagIcon, GitCompareIcon, GitCompare, Play, MoreVertical, AlertTriangle, ChevronLeftIcon, PanelRightIcon, PlayIcon, ClockIcon, CrosshairIcon, SearchCodeIcon, BanIcon, KeyboardIcon, CircleSlash, FolderOpen, File as File$1, Image, FileCode, Cloud, Zap, Sparkles, Eye, FileCode2, Code, Server, Home, Package, Github } from 'lucide-react';
3
+ import { CheckIcon as CheckIcon$1, CopyIcon, ShieldAlert, ChevronDown, ChevronRight, RefreshCw, Tag, Wand2, InfoIcon as InfoIcon$1, AlertCircle, TriangleAlert, ChevronUpIcon, CheckCircleIcon, X, CircleCheck, CircleX, CircleAlert, Info, Share2, Check, TerminalSquare, FolderTree, HardDrive, Clock as Clock$1, PlayCircle, Workflow, Layers, List, CalendarClock, Timer, CornerDownRight, GitBranch, Repeat, Repeat1, Network, TriangleAlertIcon, SearchIcon, XIcon, CalendarIcon, CircleAlertIcon, Braces, ChevronDownIcon, Brackets, PlusIcon, TrashIcon, Plus, Loader2, Circle, EyeOffIcon, EyeIcon, PauseIcon, HourglassIcon, CircleDashed, Footprints, Minus, Maximize, AlertCircleIcon, StopCircle, CirclePause, Cpu, ChevronsUpDown, Search, ArrowRight, ArrowLeft, Brain, Unplug, XCircle, CloudCog, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, SaveIcon, Database, Code2, Type, ToggleLeft, Hash, Ban, ListX, ChevronsLeft, ChevronsRight, ChevronLeft, Text, TextSearch, EqualNot, Equal, Component, Trash2, Ruler, Trash, Link2, ExternalLink, MoveRight, Copy, BookOpen, ArrowLeftIcon, ArrowRightIcon, ChevronsRightIcon, AlignLeftIcon, AlignJustifyIcon, ArrowUpIcon, ArrowDownIcon, ChevronRightIcon, GaugeIcon, ChevronsLeftRightEllipsisIcon, CalculatorIcon, HashIcon, FileInputIcon, FileOutputIcon, ReceiptText, Save, RotateCcw, GripVertical, Folder, Pencil, CopyPlus, RefreshCcwIcon, Plug, LaptopMinimal, AlignLeft, Trash2Icon, File as File$1, FolderOpen, Image, FileJson, FileCode, Drill, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, AlertTriangleIcon, FrownIcon, CircleChevronUpIcon, CircleChevronDownIcon, FileIcon, ChevronsUpIcon, ChevronsDownIcon, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, CircleDashedIcon, ArrowRightToLineIcon, CoinsIcon, BracesIcon, CircleGaugeIcon, PanelTopIcon, DatabaseIcon, ListTreeIcon, PanelLeftIcon, Upload, MoveRightIcon, History, ScaleIcon, Download, FolderPlus, FolderOutput, EllipsisVerticalIcon, FileCodeIcon, Calendar1Icon, HistoryIcon, TagIcon, GitCompareIcon, GitCompare, Play, MoreVertical, AlertTriangle, ChevronLeftIcon, PanelRightIcon, PlayIcon, OctagonAlertIcon, ClockIcon, CrosshairIcon, SearchCodeIcon, BanIcon, KeyboardIcon, CircleSlash, Cloud, Zap, Sparkles, Eye, FileCode2, Code, Server, Home, Package, Github } from 'lucide-react';
4
4
  import * as React from 'react';
5
5
  import React__default, { useState, memo, useEffect, useRef, useCallback, forwardRef, useMemo, createContext, useContext, Fragment as Fragment$1, useId, Suspense, useEffectEvent, useLayoutEffect } from 'react';
6
6
  import { S as Shadows, G as Glows, B as BorderColors, C as Colors, a as Sizes, F as FontSizes, L as LineHeights, b as BorderRadius, c as Spacings } from './spacings-BcklbBjE.js';
@@ -73,14 +73,16 @@ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
73
73
  import * as SwitchPrimitives from '@radix-ui/react-switch';
74
74
  import { githubDarkInit } from '@uiw/codemirror-theme-github';
75
75
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
76
+ import { coreFeatures } from '@mastra/core/features';
76
77
  import { format as format$1 } from 'date-fns/format';
77
78
  import { EntityType } from '@mastra/core/observability';
78
79
  import Papa from 'papaparse';
79
80
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
80
81
  import { createPortal } from 'react-dom';
81
82
  import { Command as Command$1 } from 'cmdk';
83
+ import { EditorState } from '@codemirror/state';
84
+ import { MergeView } from '@codemirror/merge';
82
85
  import { Prism } from 'react-syntax-highlighter';
83
- import { coreFeatures } from '@mastra/core/features';
84
86
  import { s as shouldRetryWorkspaceQuery, i as isWorkspaceV1Supported } from './compatibility-f2FIOihW.js';
85
87
  export { a as isWorkspaceNotSupportedError } from './compatibility-f2FIOihW.js';
86
88
 
@@ -576,7 +578,7 @@ const fromTheme = key => {
576
578
  };
577
579
  const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
578
580
  const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
579
- const fractionRegex = /^\d+\/\d+$/;
581
+ const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
580
582
  const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
581
583
  const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
582
584
  const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
@@ -602,6 +604,8 @@ const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever
602
604
  const isArbitraryValue = value => arbitraryValueRegex.test(value);
603
605
  const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
604
606
  const isArbitraryNumber = value => getIsArbitraryValue(value, isLabelNumber, isNumber);
607
+ const isArbitraryWeight = value => getIsArbitraryValue(value, isLabelWeight, isAny);
608
+ const isArbitraryFamilyName = value => getIsArbitraryValue(value, isLabelFamilyName, isNever);
605
609
  const isArbitraryPosition = value => getIsArbitraryValue(value, isLabelPosition, isNever);
606
610
  const isArbitraryImage = value => getIsArbitraryValue(value, isLabelImage, isImage);
607
611
  const isArbitraryShadow = value => getIsArbitraryValue(value, isLabelShadow, isShadow);
@@ -612,6 +616,7 @@ const isArbitraryVariablePosition = value => getIsArbitraryVariable(value, isLab
612
616
  const isArbitraryVariableSize = value => getIsArbitraryVariable(value, isLabelSize);
613
617
  const isArbitraryVariableImage = value => getIsArbitraryVariable(value, isLabelImage);
614
618
  const isArbitraryVariableShadow = value => getIsArbitraryVariable(value, isLabelShadow, true);
619
+ const isArbitraryVariableWeight = value => getIsArbitraryVariable(value, isLabelWeight, true);
615
620
  // Helpers
616
621
  const getIsArbitraryValue = (value, testLabel, testValue) => {
617
622
  const result = arbitraryValueRegex.exec(value);
@@ -640,6 +645,7 @@ const isLabelSize = label => label === 'length' || label === 'size' || label ===
640
645
  const isLabelLength = label => label === 'length';
641
646
  const isLabelNumber = label => label === 'number';
642
647
  const isLabelFamilyName = label => label === 'family-name';
648
+ const isLabelWeight = label => label === 'number' || label === 'weight';
643
649
  const isLabelShadow = label => label === 'shadow';
644
650
  const getDefaultConfig = () => {
645
651
  /**
@@ -698,6 +704,8 @@ const getDefaultConfig = () => {
698
704
  const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
699
705
  const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
700
706
  const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
707
+ const scaleSizingInline = () => [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
708
+ const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
701
709
  const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
702
710
  const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
703
711
  position: [isArbitraryVariable, isArbitraryValue]
@@ -896,40 +904,66 @@ const getDefaultConfig = () => {
896
904
  */
897
905
  position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
898
906
  /**
899
- * Top / Right / Bottom / Left
907
+ * Inset
900
908
  * @see https://tailwindcss.com/docs/top-right-bottom-left
901
909
  */
902
910
  inset: [{
903
911
  inset: scaleInset()
904
912
  }],
905
913
  /**
906
- * Right / Left
914
+ * Inset Inline
907
915
  * @see https://tailwindcss.com/docs/top-right-bottom-left
908
916
  */
909
917
  'inset-x': [{
910
918
  'inset-x': scaleInset()
911
919
  }],
912
920
  /**
913
- * Top / Bottom
921
+ * Inset Block
914
922
  * @see https://tailwindcss.com/docs/top-right-bottom-left
915
923
  */
916
924
  'inset-y': [{
917
925
  'inset-y': scaleInset()
918
926
  }],
919
927
  /**
920
- * Start
928
+ * Inset Inline Start
921
929
  * @see https://tailwindcss.com/docs/top-right-bottom-left
930
+ * @todo class group will be renamed to `inset-s` in next major release
922
931
  */
923
932
  start: [{
933
+ 'inset-s': scaleInset(),
934
+ /**
935
+ * @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
936
+ * @see https://github.com/tailwindlabs/tailwindcss/pull/19613
937
+ */
924
938
  start: scaleInset()
925
939
  }],
926
940
  /**
927
- * End
941
+ * Inset Inline End
928
942
  * @see https://tailwindcss.com/docs/top-right-bottom-left
943
+ * @todo class group will be renamed to `inset-e` in next major release
929
944
  */
930
945
  end: [{
946
+ 'inset-e': scaleInset(),
947
+ /**
948
+ * @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
949
+ * @see https://github.com/tailwindlabs/tailwindcss/pull/19613
950
+ */
931
951
  end: scaleInset()
932
952
  }],
953
+ /**
954
+ * Inset Block Start
955
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
956
+ */
957
+ 'inset-bs': [{
958
+ 'inset-bs': scaleInset()
959
+ }],
960
+ /**
961
+ * Inset Block End
962
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
963
+ */
964
+ 'inset-be': [{
965
+ 'inset-be': scaleInset()
966
+ }],
933
967
  /**
934
968
  * Top
935
969
  * @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -1196,33 +1230,47 @@ const getDefaultConfig = () => {
1196
1230
  p: scaleUnambiguousSpacing()
1197
1231
  }],
1198
1232
  /**
1199
- * Padding X
1233
+ * Padding Inline
1200
1234
  * @see https://tailwindcss.com/docs/padding
1201
1235
  */
1202
1236
  px: [{
1203
1237
  px: scaleUnambiguousSpacing()
1204
1238
  }],
1205
1239
  /**
1206
- * Padding Y
1240
+ * Padding Block
1207
1241
  * @see https://tailwindcss.com/docs/padding
1208
1242
  */
1209
1243
  py: [{
1210
1244
  py: scaleUnambiguousSpacing()
1211
1245
  }],
1212
1246
  /**
1213
- * Padding Start
1247
+ * Padding Inline Start
1214
1248
  * @see https://tailwindcss.com/docs/padding
1215
1249
  */
1216
1250
  ps: [{
1217
1251
  ps: scaleUnambiguousSpacing()
1218
1252
  }],
1219
1253
  /**
1220
- * Padding End
1254
+ * Padding Inline End
1221
1255
  * @see https://tailwindcss.com/docs/padding
1222
1256
  */
1223
1257
  pe: [{
1224
1258
  pe: scaleUnambiguousSpacing()
1225
1259
  }],
1260
+ /**
1261
+ * Padding Block Start
1262
+ * @see https://tailwindcss.com/docs/padding
1263
+ */
1264
+ pbs: [{
1265
+ pbs: scaleUnambiguousSpacing()
1266
+ }],
1267
+ /**
1268
+ * Padding Block End
1269
+ * @see https://tailwindcss.com/docs/padding
1270
+ */
1271
+ pbe: [{
1272
+ pbe: scaleUnambiguousSpacing()
1273
+ }],
1226
1274
  /**
1227
1275
  * Padding Top
1228
1276
  * @see https://tailwindcss.com/docs/padding
@@ -1259,33 +1307,47 @@ const getDefaultConfig = () => {
1259
1307
  m: scaleMargin()
1260
1308
  }],
1261
1309
  /**
1262
- * Margin X
1310
+ * Margin Inline
1263
1311
  * @see https://tailwindcss.com/docs/margin
1264
1312
  */
1265
1313
  mx: [{
1266
1314
  mx: scaleMargin()
1267
1315
  }],
1268
1316
  /**
1269
- * Margin Y
1317
+ * Margin Block
1270
1318
  * @see https://tailwindcss.com/docs/margin
1271
1319
  */
1272
1320
  my: [{
1273
1321
  my: scaleMargin()
1274
1322
  }],
1275
1323
  /**
1276
- * Margin Start
1324
+ * Margin Inline Start
1277
1325
  * @see https://tailwindcss.com/docs/margin
1278
1326
  */
1279
1327
  ms: [{
1280
1328
  ms: scaleMargin()
1281
1329
  }],
1282
1330
  /**
1283
- * Margin End
1331
+ * Margin Inline End
1284
1332
  * @see https://tailwindcss.com/docs/margin
1285
1333
  */
1286
1334
  me: [{
1287
1335
  me: scaleMargin()
1288
1336
  }],
1337
+ /**
1338
+ * Margin Block Start
1339
+ * @see https://tailwindcss.com/docs/margin
1340
+ */
1341
+ mbs: [{
1342
+ mbs: scaleMargin()
1343
+ }],
1344
+ /**
1345
+ * Margin Block End
1346
+ * @see https://tailwindcss.com/docs/margin
1347
+ */
1348
+ mbe: [{
1349
+ mbe: scaleMargin()
1350
+ }],
1289
1351
  /**
1290
1352
  * Margin Top
1291
1353
  * @see https://tailwindcss.com/docs/margin
@@ -1348,6 +1410,48 @@ const getDefaultConfig = () => {
1348
1410
  size: [{
1349
1411
  size: scaleSizing()
1350
1412
  }],
1413
+ /**
1414
+ * Inline Size
1415
+ * @see https://tailwindcss.com/docs/width
1416
+ */
1417
+ 'inline-size': [{
1418
+ inline: ['auto', ...scaleSizingInline()]
1419
+ }],
1420
+ /**
1421
+ * Min-Inline Size
1422
+ * @see https://tailwindcss.com/docs/min-width
1423
+ */
1424
+ 'min-inline-size': [{
1425
+ 'min-inline': ['auto', ...scaleSizingInline()]
1426
+ }],
1427
+ /**
1428
+ * Max-Inline Size
1429
+ * @see https://tailwindcss.com/docs/max-width
1430
+ */
1431
+ 'max-inline-size': [{
1432
+ 'max-inline': ['none', ...scaleSizingInline()]
1433
+ }],
1434
+ /**
1435
+ * Block Size
1436
+ * @see https://tailwindcss.com/docs/height
1437
+ */
1438
+ 'block-size': [{
1439
+ block: ['auto', ...scaleSizingBlock()]
1440
+ }],
1441
+ /**
1442
+ * Min-Block Size
1443
+ * @see https://tailwindcss.com/docs/min-height
1444
+ */
1445
+ 'min-block-size': [{
1446
+ 'min-block': ['auto', ...scaleSizingBlock()]
1447
+ }],
1448
+ /**
1449
+ * Max-Block Size
1450
+ * @see https://tailwindcss.com/docs/max-height
1451
+ */
1452
+ 'max-block-size': [{
1453
+ 'max-block': ['none', ...scaleSizingBlock()]
1454
+ }],
1351
1455
  /**
1352
1456
  * Width
1353
1457
  * @see https://tailwindcss.com/docs/width
@@ -1420,7 +1524,7 @@ const getDefaultConfig = () => {
1420
1524
  * @see https://tailwindcss.com/docs/font-weight
1421
1525
  */
1422
1526
  'font-weight': [{
1423
- font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
1527
+ font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
1424
1528
  }],
1425
1529
  /**
1426
1530
  * Font Stretch
@@ -1434,7 +1538,14 @@ const getDefaultConfig = () => {
1434
1538
  * @see https://tailwindcss.com/docs/font-family
1435
1539
  */
1436
1540
  'font-family': [{
1437
- font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
1541
+ font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
1542
+ }],
1543
+ /**
1544
+ * Font Feature Settings
1545
+ * @see https://tailwindcss.com/docs/font-feature-settings
1546
+ */
1547
+ 'font-features': [{
1548
+ 'font-features': [isArbitraryValue]
1438
1549
  }],
1439
1550
  /**
1440
1551
  * Font Variant Numeric
@@ -1853,33 +1964,47 @@ const getDefaultConfig = () => {
1853
1964
  border: scaleBorderWidth()
1854
1965
  }],
1855
1966
  /**
1856
- * Border Width X
1967
+ * Border Width Inline
1857
1968
  * @see https://tailwindcss.com/docs/border-width
1858
1969
  */
1859
1970
  'border-w-x': [{
1860
1971
  'border-x': scaleBorderWidth()
1861
1972
  }],
1862
1973
  /**
1863
- * Border Width Y
1974
+ * Border Width Block
1864
1975
  * @see https://tailwindcss.com/docs/border-width
1865
1976
  */
1866
1977
  'border-w-y': [{
1867
1978
  'border-y': scaleBorderWidth()
1868
1979
  }],
1869
1980
  /**
1870
- * Border Width Start
1981
+ * Border Width Inline Start
1871
1982
  * @see https://tailwindcss.com/docs/border-width
1872
1983
  */
1873
1984
  'border-w-s': [{
1874
1985
  'border-s': scaleBorderWidth()
1875
1986
  }],
1876
1987
  /**
1877
- * Border Width End
1988
+ * Border Width Inline End
1878
1989
  * @see https://tailwindcss.com/docs/border-width
1879
1990
  */
1880
1991
  'border-w-e': [{
1881
1992
  'border-e': scaleBorderWidth()
1882
1993
  }],
1994
+ /**
1995
+ * Border Width Block Start
1996
+ * @see https://tailwindcss.com/docs/border-width
1997
+ */
1998
+ 'border-w-bs': [{
1999
+ 'border-bs': scaleBorderWidth()
2000
+ }],
2001
+ /**
2002
+ * Border Width Block End
2003
+ * @see https://tailwindcss.com/docs/border-width
2004
+ */
2005
+ 'border-w-be': [{
2006
+ 'border-be': scaleBorderWidth()
2007
+ }],
1883
2008
  /**
1884
2009
  * Border Width Top
1885
2010
  * @see https://tailwindcss.com/docs/border-width
@@ -1954,33 +2079,47 @@ const getDefaultConfig = () => {
1954
2079
  border: scaleColor()
1955
2080
  }],
1956
2081
  /**
1957
- * Border Color X
2082
+ * Border Color Inline
1958
2083
  * @see https://tailwindcss.com/docs/border-color
1959
2084
  */
1960
2085
  'border-color-x': [{
1961
2086
  'border-x': scaleColor()
1962
2087
  }],
1963
2088
  /**
1964
- * Border Color Y
2089
+ * Border Color Block
1965
2090
  * @see https://tailwindcss.com/docs/border-color
1966
2091
  */
1967
2092
  'border-color-y': [{
1968
2093
  'border-y': scaleColor()
1969
2094
  }],
1970
2095
  /**
1971
- * Border Color S
2096
+ * Border Color Inline Start
1972
2097
  * @see https://tailwindcss.com/docs/border-color
1973
2098
  */
1974
2099
  'border-color-s': [{
1975
2100
  'border-s': scaleColor()
1976
2101
  }],
1977
2102
  /**
1978
- * Border Color E
2103
+ * Border Color Inline End
1979
2104
  * @see https://tailwindcss.com/docs/border-color
1980
2105
  */
1981
2106
  'border-color-e': [{
1982
2107
  'border-e': scaleColor()
1983
2108
  }],
2109
+ /**
2110
+ * Border Color Block Start
2111
+ * @see https://tailwindcss.com/docs/border-color
2112
+ */
2113
+ 'border-color-bs': [{
2114
+ 'border-bs': scaleColor()
2115
+ }],
2116
+ /**
2117
+ * Border Color Block End
2118
+ * @see https://tailwindcss.com/docs/border-color
2119
+ */
2120
+ 'border-color-be': [{
2121
+ 'border-be': scaleColor()
2122
+ }],
1984
2123
  /**
1985
2124
  * Border Color Top
1986
2125
  * @see https://tailwindcss.com/docs/border-color
@@ -2841,33 +2980,47 @@ const getDefaultConfig = () => {
2841
2980
  'scroll-m': scaleUnambiguousSpacing()
2842
2981
  }],
2843
2982
  /**
2844
- * Scroll Margin X
2983
+ * Scroll Margin Inline
2845
2984
  * @see https://tailwindcss.com/docs/scroll-margin
2846
2985
  */
2847
2986
  'scroll-mx': [{
2848
2987
  'scroll-mx': scaleUnambiguousSpacing()
2849
2988
  }],
2850
2989
  /**
2851
- * Scroll Margin Y
2990
+ * Scroll Margin Block
2852
2991
  * @see https://tailwindcss.com/docs/scroll-margin
2853
2992
  */
2854
2993
  'scroll-my': [{
2855
2994
  'scroll-my': scaleUnambiguousSpacing()
2856
2995
  }],
2857
2996
  /**
2858
- * Scroll Margin Start
2997
+ * Scroll Margin Inline Start
2859
2998
  * @see https://tailwindcss.com/docs/scroll-margin
2860
2999
  */
2861
3000
  'scroll-ms': [{
2862
3001
  'scroll-ms': scaleUnambiguousSpacing()
2863
3002
  }],
2864
3003
  /**
2865
- * Scroll Margin End
3004
+ * Scroll Margin Inline End
2866
3005
  * @see https://tailwindcss.com/docs/scroll-margin
2867
3006
  */
2868
3007
  'scroll-me': [{
2869
3008
  'scroll-me': scaleUnambiguousSpacing()
2870
3009
  }],
3010
+ /**
3011
+ * Scroll Margin Block Start
3012
+ * @see https://tailwindcss.com/docs/scroll-margin
3013
+ */
3014
+ 'scroll-mbs': [{
3015
+ 'scroll-mbs': scaleUnambiguousSpacing()
3016
+ }],
3017
+ /**
3018
+ * Scroll Margin Block End
3019
+ * @see https://tailwindcss.com/docs/scroll-margin
3020
+ */
3021
+ 'scroll-mbe': [{
3022
+ 'scroll-mbe': scaleUnambiguousSpacing()
3023
+ }],
2871
3024
  /**
2872
3025
  * Scroll Margin Top
2873
3026
  * @see https://tailwindcss.com/docs/scroll-margin
@@ -2904,33 +3057,47 @@ const getDefaultConfig = () => {
2904
3057
  'scroll-p': scaleUnambiguousSpacing()
2905
3058
  }],
2906
3059
  /**
2907
- * Scroll Padding X
3060
+ * Scroll Padding Inline
2908
3061
  * @see https://tailwindcss.com/docs/scroll-padding
2909
3062
  */
2910
3063
  'scroll-px': [{
2911
3064
  'scroll-px': scaleUnambiguousSpacing()
2912
3065
  }],
2913
3066
  /**
2914
- * Scroll Padding Y
3067
+ * Scroll Padding Block
2915
3068
  * @see https://tailwindcss.com/docs/scroll-padding
2916
3069
  */
2917
3070
  'scroll-py': [{
2918
3071
  'scroll-py': scaleUnambiguousSpacing()
2919
3072
  }],
2920
3073
  /**
2921
- * Scroll Padding Start
3074
+ * Scroll Padding Inline Start
2922
3075
  * @see https://tailwindcss.com/docs/scroll-padding
2923
3076
  */
2924
3077
  'scroll-ps': [{
2925
3078
  'scroll-ps': scaleUnambiguousSpacing()
2926
3079
  }],
2927
3080
  /**
2928
- * Scroll Padding End
3081
+ * Scroll Padding Inline End
2929
3082
  * @see https://tailwindcss.com/docs/scroll-padding
2930
3083
  */
2931
3084
  'scroll-pe': [{
2932
3085
  'scroll-pe': scaleUnambiguousSpacing()
2933
3086
  }],
3087
+ /**
3088
+ * Scroll Padding Block Start
3089
+ * @see https://tailwindcss.com/docs/scroll-padding
3090
+ */
3091
+ 'scroll-pbs': [{
3092
+ 'scroll-pbs': scaleUnambiguousSpacing()
3093
+ }],
3094
+ /**
3095
+ * Scroll Padding Block End
3096
+ * @see https://tailwindcss.com/docs/scroll-padding
3097
+ */
3098
+ 'scroll-pbe': [{
3099
+ 'scroll-pbe': scaleUnambiguousSpacing()
3100
+ }],
2934
3101
  /**
2935
3102
  * Scroll Padding Top
2936
3103
  * @see https://tailwindcss.com/docs/scroll-padding
@@ -3065,15 +3232,15 @@ const getDefaultConfig = () => {
3065
3232
  conflictingClassGroups: {
3066
3233
  overflow: ['overflow-x', 'overflow-y'],
3067
3234
  overscroll: ['overscroll-x', 'overscroll-y'],
3068
- inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
3235
+ inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
3069
3236
  'inset-x': ['right', 'left'],
3070
3237
  'inset-y': ['top', 'bottom'],
3071
3238
  flex: ['basis', 'grow', 'shrink'],
3072
3239
  gap: ['gap-x', 'gap-y'],
3073
- p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
3240
+ p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
3074
3241
  px: ['pr', 'pl'],
3075
3242
  py: ['pt', 'pb'],
3076
- m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
3243
+ m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
3077
3244
  mx: ['mr', 'ml'],
3078
3245
  my: ['mt', 'mb'],
3079
3246
  size: ['w', 'h'],
@@ -3093,18 +3260,18 @@ const getDefaultConfig = () => {
3093
3260
  'rounded-b': ['rounded-br', 'rounded-bl'],
3094
3261
  'rounded-l': ['rounded-tl', 'rounded-bl'],
3095
3262
  'border-spacing': ['border-spacing-x', 'border-spacing-y'],
3096
- 'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
3263
+ 'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
3097
3264
  'border-w-x': ['border-w-r', 'border-w-l'],
3098
3265
  'border-w-y': ['border-w-t', 'border-w-b'],
3099
- 'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
3266
+ 'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
3100
3267
  'border-color-x': ['border-color-r', 'border-color-l'],
3101
3268
  'border-color-y': ['border-color-t', 'border-color-b'],
3102
3269
  translate: ['translate-x', 'translate-y', 'translate-none'],
3103
3270
  'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
3104
- 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
3271
+ 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
3105
3272
  'scroll-mx': ['scroll-mr', 'scroll-ml'],
3106
3273
  'scroll-my': ['scroll-mt', 'scroll-mb'],
3107
- 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
3274
+ 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
3108
3275
  'scroll-px': ['scroll-pr', 'scroll-pl'],
3109
3276
  'scroll-py': ['scroll-pt', 'scroll-pb'],
3110
3277
  touch: ['touch-x', 'touch-y', 'touch-pz'],
@@ -7442,8 +7609,17 @@ function SelectField$1({
7442
7609
  required && /* @__PURE__ */ jsx("i", { className: "text-neutral2", children: "(required)" })
7443
7610
  ] }) }),
7444
7611
  /* @__PURE__ */ jsxs(Select, { name, value, onValueChange, disabled, children: [
7445
- /* @__PURE__ */ jsx(SelectTrigger, { id: `select-${name}`, size, variant, children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }),
7446
- /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap truncate flex items-center gap-2", children: [
7612
+ /* @__PURE__ */ jsx(
7613
+ SelectTrigger,
7614
+ {
7615
+ id: `select-${name}`,
7616
+ size,
7617
+ variant,
7618
+ className: "grid grid-cols-[1fr_auto] [&>span]:truncate",
7619
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
7620
+ }
7621
+ ),
7622
+ /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, disabled: option.disabled, children: /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap truncate flex items-center gap-2", children: [
7447
7623
  option.icon,
7448
7624
  option.label
7449
7625
  ] }) }, option.label)) })
@@ -18841,7 +19017,7 @@ function SideDialogHeading({ children, className, as = "h1" }) {
18841
19017
  }
18842
19018
 
18843
19019
  function SideDialogContent({ children, className }) {
18844
- return /* @__PURE__ */ jsx("div", { className: cn("p-6 pl-9 overflow-y-scroll grid gap-6 content-start", className), children: /* @__PURE__ */ jsx("div", { className: cn("grid gap-6 mb-8"), children }) });
19020
+ return /* @__PURE__ */ jsx("div", { className: cn("p-6 pl-9 overflow-y-scroll grid gap-6 content-start pb-8", className), children });
18845
19021
  }
18846
19022
 
18847
19023
  function SideDialogHeader({ children, className }) {
@@ -19855,7 +20031,7 @@ const useCompareScorerVersions = ({
19855
20031
  });
19856
20032
  };
19857
20033
 
19858
- function formatTimestamp$1(isoString) {
20034
+ function formatTimestamp$2(isoString) {
19859
20035
  const date = new Date(isoString);
19860
20036
  return date.toLocaleDateString(void 0, {
19861
20037
  month: "short",
@@ -19889,7 +20065,7 @@ function ScorerVersionCombobox({
19889
20065
  return {
19890
20066
  label: `v${version.versionNumber}`,
19891
20067
  value: version.id,
19892
- description: formatTimestamp$1(version.createdAt),
20068
+ description: formatTimestamp$2(version.createdAt),
19893
20069
  end: isPublished ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Published" }) : isDraft ? /* @__PURE__ */ jsx(Badge, { variant: "info", children: "Draft" }) : void 0
19894
20070
  };
19895
20071
  })
@@ -22470,6 +22646,12 @@ const entityConfigSchema = z.object({
22470
22646
  description: z.string().max(500).optional(),
22471
22647
  rules: ruleGroupSchema.optional()
22472
22648
  });
22649
+ const skillConfigSchema = z.object({
22650
+ description: z.string().optional(),
22651
+ instructions: z.string().optional(),
22652
+ pin: z.string().optional(),
22653
+ strategy: z.enum(["latest", "live"]).optional()
22654
+ });
22473
22655
  const scorerConfigSchema = z.object({
22474
22656
  description: z.string().max(500).optional(),
22475
22657
  sampling: scoringSamplingConfigSchema.optional(),
@@ -22523,6 +22705,22 @@ const memoryConfigSchema = z.object({
22523
22705
  path: ["semanticRecall"]
22524
22706
  }
22525
22707
  );
22708
+ const inMemoryFileNodeSchema = z.lazy(
22709
+ () => z.object({
22710
+ id: z.string(),
22711
+ name: z.string(),
22712
+ type: z.enum(["file", "folder"]),
22713
+ content: z.string().optional(),
22714
+ children: z.array(inMemoryFileNodeSchema).optional()
22715
+ })
22716
+ );
22717
+ z.object({
22718
+ localId: z.string(),
22719
+ name: z.string().min(1, "Skill name is required"),
22720
+ description: z.string(),
22721
+ workspaceId: z.string().min(1, "Workspace is required"),
22722
+ files: z.array(inMemoryFileNodeSchema)
22723
+ });
22526
22724
  const agentFormSchema = z.object({
22527
22725
  name: z.string().min(1, "Name is required").max(100, "Name must be 100 characters or less"),
22528
22726
  description: z.string().max(500, "Description must be 500 characters or less").optional(),
@@ -22544,10 +22742,21 @@ const agentFormSchema = z.object({
22544
22742
  id: z.string().optional(),
22545
22743
  name: z.string().min(1),
22546
22744
  description: z.string().optional(),
22547
- servers: z.record(z.string(), z.any())
22745
+ servers: z.record(z.string(), z.any()),
22746
+ selectedTools: z.record(
22747
+ z.string(),
22748
+ z.object({
22749
+ description: z.string().optional()
22750
+ })
22751
+ ).optional().default({})
22548
22752
  })
22549
22753
  ).optional().default([]),
22550
- mcpClientsToDelete: z.array(z.string()).optional().default([])
22754
+ mcpClientsToDelete: z.array(z.string()).optional().default([]),
22755
+ skills: z.record(z.string(), skillConfigSchema).optional().default({}),
22756
+ workspace: z.discriminatedUnion("type", [
22757
+ z.object({ type: z.literal("id"), workspaceId: z.string() }),
22758
+ z.object({ type: z.literal("inline"), config: z.record(z.string(), z.unknown()) })
22759
+ ]).optional()
22551
22760
  });
22552
22761
 
22553
22762
  const AgentCMSBlocks = ({ items, onChange, className, placeholder, schema }) => {
@@ -22636,7 +22845,8 @@ function useAgentEditForm(options = {}) {
22636
22845
  variables: initialValues?.variables ?? {},
22637
22846
  instructionBlocks: initialValues?.instructionBlocks ?? [createInstructionBlock()],
22638
22847
  mcpClients: initialValues?.mcpClients ?? [],
22639
- mcpClientsToDelete: []
22848
+ mcpClientsToDelete: [],
22849
+ skills: initialValues?.skills ?? {}
22640
22850
  }
22641
22851
  });
22642
22852
  return { form };
@@ -23774,7 +23984,7 @@ function MemorySection({ control, setValue, readOnly = false }) {
23774
23984
  ] }) });
23775
23985
  }
23776
23986
 
23777
- function formatTimestamp(isoString) {
23987
+ function formatTimestamp$1(isoString) {
23778
23988
  const date = new Date(isoString);
23779
23989
  return date.toLocaleDateString(void 0, {
23780
23990
  month: "short",
@@ -23808,7 +24018,7 @@ function AgentVersionCombobox({
23808
24018
  return {
23809
24019
  label: `v${version.versionNumber}`,
23810
24020
  value: version.id,
23811
- description: formatTimestamp(version.createdAt),
24021
+ description: formatTimestamp$1(version.createdAt),
23812
24022
  end: isPublished ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Published" }) : isDraft ? /* @__PURE__ */ jsx(Badge, { variant: "info", children: "Draft" }) : void 0
23813
24023
  };
23814
24024
  })
@@ -23847,6 +24057,8 @@ function useSidebarDescriptions(control) {
23847
24057
  const workflowCount = Object.keys(values.workflows ?? {}).length;
23848
24058
  const workflows = workflowCount === 0 ? "None selected" : pluralize(workflowCount, "workflow");
23849
24059
  const memory = values.memory?.enabled ? "Enabled" : "Disabled";
24060
+ const skillCount = Object.keys(values.skills ?? {}).length;
24061
+ const skills = skillCount === 0 ? "None selected" : pluralize(skillCount, "skill");
23850
24062
  const variableCount = Object.keys(values.variables?.properties ?? {}).length;
23851
24063
  const variables = variableCount === 0 ? "None defined" : pluralize(variableCount, "variable");
23852
24064
  return {
@@ -23856,6 +24068,7 @@ function useSidebarDescriptions(control) {
23856
24068
  agents: { description: agents, done: agentCount > 0 },
23857
24069
  scorers: { description: scorers, done: scorerCount > 0 },
23858
24070
  workflows: { description: workflows, done: workflowCount > 0 },
24071
+ skills: { description: skills, done: skillCount > 0 },
23859
24072
  memory: { description: memory, done: !!values.memory?.enabled },
23860
24073
  variables: { description: variables, done: variableCount > 0 }
23861
24074
  };
@@ -23869,6 +24082,7 @@ const AGENT_CMS_SECTIONS = [
23869
24082
  { name: "Agents", pathSuffix: "/agents", descriptionKey: "agents", required: false },
23870
24083
  { name: "Scorers", pathSuffix: "/scorers", descriptionKey: "scorers", required: false },
23871
24084
  { name: "Workflows", pathSuffix: "/workflows", descriptionKey: "workflows", required: false },
24085
+ { name: "Skills", pathSuffix: "/skills", descriptionKey: "skills", required: false },
23872
24086
  { name: "Memory", pathSuffix: "/memory", descriptionKey: "memory", required: false },
23873
24087
  { name: "Variables", pathSuffix: "/variables", descriptionKey: "variables", required: false }
23874
24088
  ];
@@ -23982,14 +24196,24 @@ function AgentCmsBottomBar({ basePath, currentPath }) {
23982
24196
  ] });
23983
24197
  }
23984
24198
 
23985
- function AgentsCmsLayout({ children, currentPath, basePath, versionId }) {
23986
- return /* @__PURE__ */ jsxs("div", { className: "grid overflow-y-auto h-full bg-surface1 grid-cols-[240px_1fr]", children: [
23987
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto h-full border-r border-border1", children: /* @__PURE__ */ jsx(AgentCmsSidebar, { basePath, currentPath, versionId }) }),
23988
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
23989
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto flex-1 p-8 max-w-5xl w-full", children }),
23990
- /* @__PURE__ */ jsx(AgentCmsBottomBar, { basePath, currentPath })
23991
- ] })
23992
- ] });
24199
+ function AgentsCmsLayout({ children, currentPath, basePath, versionId, rightPanel }) {
24200
+ return /* @__PURE__ */ jsxs(
24201
+ "div",
24202
+ {
24203
+ className: cn(
24204
+ "grid overflow-y-auto h-full bg-surface1",
24205
+ rightPanel ? "grid-cols-[240px_1fr_240px]" : "grid-cols-[240px_1fr]"
24206
+ ),
24207
+ children: [
24208
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto h-full border-r border-border1", children: /* @__PURE__ */ jsx(AgentCmsSidebar, { basePath, currentPath, versionId }) }),
24209
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
24210
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto flex-1 p-8 max-w-5xl w-full", children }),
24211
+ /* @__PURE__ */ jsx(AgentCmsBottomBar, { basePath, currentPath })
24212
+ ] }),
24213
+ rightPanel && /* @__PURE__ */ jsx("div", { className: "overflow-y-auto h-full border-l border-border1", children: rightPanel })
24214
+ ]
24215
+ }
24216
+ );
23993
24217
  }
23994
24218
 
23995
24219
  function InformationPage() {
@@ -24613,6 +24837,7 @@ function MCPClientFormSidebar({
24613
24837
  onPreFillFromServer,
24614
24838
  containerRef,
24615
24839
  readOnly,
24840
+ showSubmit,
24616
24841
  submitLabel = "Create MCP Client",
24617
24842
  onTryConnect,
24618
24843
  isTryingConnect
@@ -24826,8 +25051,8 @@ function MCPClientFormSidebar({
24826
25051
  ] })
24827
25052
  ] })
24828
25053
  ] }) }),
24829
- !readOnly && /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 p-4 flex flex-col gap-2", children: [
24830
- (() => {
25054
+ (showSubmit ?? !readOnly) && /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 p-4 flex flex-col gap-2", children: [
25055
+ !readOnly && (() => {
24831
25056
  const isDisabled = serverType !== "http" || !url.trim() || isTryingConnect;
24832
25057
  const tooltipContent = serverType !== "http" ? "Only available for HTTP servers" : !url.trim() ? "Enter a URL first" : void 0;
24833
25058
  return tooltipContent ? /* @__PURE__ */ jsx(
@@ -24859,7 +25084,14 @@ function MCPClientFormSidebar({
24859
25084
  ] });
24860
25085
  }
24861
25086
 
24862
- function MCPClientToolPreview({ serverType, url, tryConnect }) {
25087
+ function MCPClientToolPreview({
25088
+ serverType,
25089
+ url,
25090
+ tryConnect,
25091
+ selectedTools,
25092
+ onToggleTool,
25093
+ onDescriptionChange
25094
+ }) {
24863
25095
  if (serverType === "stdio") {
24864
25096
  return /* @__PURE__ */ jsx(EmptyState, { children: /* @__PURE__ */ jsx(Txt, { className: "text-neutral3", children: "Tool preview is available for HTTP servers. Stdio servers cannot be previewed." }) });
24865
25097
  }
@@ -24876,37 +25108,79 @@ function MCPClientToolPreview({ serverType, url, tryConnect }) {
24876
25108
  ] }),
24877
25109
  tryConnect.isError && /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-accent2", children: tryConnect.error instanceof Error ? tryConnect.error.message : "Connection failed" }),
24878
25110
  tryConnect.isSuccess && tryConnect.data.tools.length === 0 && /* @__PURE__ */ jsx(Txt, { className: "text-neutral3", children: "Connected successfully but no tools were found." }),
24879
- tryConnect.isSuccess && tryConnect.data.tools.length > 0 && /* @__PURE__ */ jsx(ToolList, { tools: tryConnect.data.tools })
25111
+ tryConnect.isSuccess && tryConnect.data.tools.length > 0 && /* @__PURE__ */ jsx(
25112
+ ToolList,
25113
+ {
25114
+ tools: tryConnect.data.tools,
25115
+ selectedTools,
25116
+ onToggleTool,
25117
+ onDescriptionChange
25118
+ }
25119
+ )
24880
25120
  ] });
24881
25121
  }
24882
25122
  function EmptyState({ children }) {
24883
25123
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full p-8 text-center", children });
24884
25124
  }
24885
- function ToolList({ tools }) {
25125
+ function ToolList({
25126
+ tools,
25127
+ selectedTools = {},
25128
+ onToggleTool,
25129
+ onDescriptionChange
25130
+ }) {
25131
+ const selectedCount = Object.keys(selectedTools).length;
24886
25132
  return /* @__PURE__ */ jsxs("div", { className: "p-5 overflow-y-auto", children: [
24887
25133
  /* @__PURE__ */ jsxs("div", { className: "text-neutral6 flex gap-2 items-center", children: [
24888
25134
  /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: /* @__PURE__ */ jsx(McpServerIcon, {}) }),
24889
25135
  /* @__PURE__ */ jsxs(Txt, { variant: "header-md", as: "h2", className: "font-medium", children: [
24890
25136
  "Available Tools (",
25137
+ selectedCount,
25138
+ "/",
24891
25139
  tools.length,
24892
- ")"
25140
+ " selected)"
24893
25141
  ] })
24894
25142
  ] }),
24895
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 pt-6", children: tools.map((tool) => /* @__PURE__ */ jsxs(Entity, { children: [
24896
- /* @__PURE__ */ jsx(EntityIcon, { children: /* @__PURE__ */ jsx(ToolsIcon, { className: "group-hover/entity:text-accent6" }) }),
24897
- /* @__PURE__ */ jsxs(EntityContent, { children: [
24898
- /* @__PURE__ */ jsx(EntityName, { children: tool.name }),
24899
- tool.description && /* @__PURE__ */ jsx(EntityDescription, { children: tool.description })
24900
- ] })
24901
- ] }, tool.name)) })
25143
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 pt-6", children: tools.map((tool) => {
25144
+ const isSelected = tool.name in selectedTools;
25145
+ const isDisabled = !onDescriptionChange || !isSelected;
25146
+ return /* @__PURE__ */ jsxs(Entity, { children: [
25147
+ /* @__PURE__ */ jsx(EntityIcon, { children: /* @__PURE__ */ jsx(ToolsIcon, { className: "group-hover/entity:text-accent6" }) }),
25148
+ /* @__PURE__ */ jsxs(EntityContent, { children: [
25149
+ /* @__PURE__ */ jsx(EntityName, { children: tool.name }),
25150
+ /* @__PURE__ */ jsx(EntityDescription, { children: /* @__PURE__ */ jsx(
25151
+ "input",
25152
+ {
25153
+ type: "text",
25154
+ disabled: isDisabled,
25155
+ className: cn(
25156
+ "border border-transparent appearance-none block w-full text-neutral3 bg-transparent",
25157
+ !isDisabled && "border-border1 border-dashed"
25158
+ ),
25159
+ value: isSelected ? selectedTools[tool.name]?.description ?? tool.description ?? "" : tool.description ?? "",
25160
+ onChange: (e) => onDescriptionChange?.(tool.name, e.target.value)
25161
+ }
25162
+ ) })
25163
+ ] }),
25164
+ onToggleTool && /* @__PURE__ */ jsx(Switch, { checked: isSelected, onCheckedChange: () => onToggleTool(tool.name, tool.description) })
25165
+ ] }, tool.name);
25166
+ }) })
24902
25167
  ] });
24903
25168
  }
24904
25169
 
24905
- function MCPClientCreateContent({ onAdd, readOnly, initialValues, submitLabel }) {
25170
+ function MCPClientCreateContent({
25171
+ onAdd,
25172
+ readOnly,
25173
+ initialValues,
25174
+ initialSelectedTools,
25175
+ submitLabel
25176
+ }) {
24906
25177
  const { form } = useMCPClientForm(initialValues);
24907
25178
  const containerRef = useRef(null);
24908
25179
  const serverType = useWatch({ control: form.control, name: "serverType" });
24909
25180
  const url = useWatch({ control: form.control, name: "url" });
25181
+ const [selectedTools, setSelectedTools] = useState(
25182
+ initialSelectedTools ?? {}
25183
+ );
24910
25184
  const tryConnect = useTryConnectMcp();
24911
25185
  const hasAutoConnected = useRef(false);
24912
25186
  useEffect(() => {
@@ -24920,6 +25194,22 @@ function MCPClientCreateContent({ onAdd, readOnly, initialValues, submitLabel })
24920
25194
  tryConnect.mutate(url);
24921
25195
  }
24922
25196
  }, [serverType, url, tryConnect]);
25197
+ const handleToggleTool = useCallback((toolName, description) => {
25198
+ setSelectedTools((prev) => {
25199
+ if (toolName in prev) {
25200
+ const next = { ...prev };
25201
+ delete next[toolName];
25202
+ return next;
25203
+ }
25204
+ return { ...prev, [toolName]: { description } };
25205
+ });
25206
+ }, []);
25207
+ const handleDescriptionChange = useCallback((toolName, description) => {
25208
+ setSelectedTools((prev) => ({
25209
+ ...prev,
25210
+ [toolName]: { ...prev[toolName], description }
25211
+ }));
25212
+ }, []);
24923
25213
  const handlePreFillFromServer = (serverId) => {
24924
25214
  const host = window.MASTRA_SERVER_HOST;
24925
25215
  const port = window.MASTRA_SERVER_PORT;
@@ -24961,7 +25251,8 @@ function MCPClientCreateContent({ onAdd, readOnly, initialValues, submitLabel })
24961
25251
  onAdd({
24962
25252
  name: values.name,
24963
25253
  description: values.description || void 0,
24964
- servers: serverConfig
25254
+ servers: serverConfig,
25255
+ selectedTools
24965
25256
  });
24966
25257
  };
24967
25258
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx(
@@ -24976,12 +25267,23 @@ function MCPClientCreateContent({ onAdd, readOnly, initialValues, submitLabel })
24976
25267
  onPreFillFromServer: handlePreFillFromServer,
24977
25268
  containerRef,
24978
25269
  readOnly,
25270
+ showSubmit: !!onAdd,
24979
25271
  submitLabel,
24980
25272
  onTryConnect: handleTryConnect,
24981
25273
  isTryingConnect: tryConnect.isPending
24982
25274
  }
24983
25275
  ),
24984
- children: /* @__PURE__ */ jsx(MCPClientToolPreview, { serverType, url, tryConnect })
25276
+ children: /* @__PURE__ */ jsx(
25277
+ MCPClientToolPreview,
25278
+ {
25279
+ serverType,
25280
+ url,
25281
+ tryConnect,
25282
+ selectedTools,
25283
+ onToggleTool: onAdd ? handleToggleTool : void 0,
25284
+ onDescriptionChange: onAdd ? handleDescriptionChange : void 0
25285
+ }
25286
+ )
24985
25287
  }
24986
25288
  ) });
24987
25289
  }
@@ -25015,11 +25317,29 @@ function MCPClientList() {
25015
25317
  const handleAdd = (config) => {
25016
25318
  const current = form.getValues("mcpClients") ?? [];
25017
25319
  form.setValue("mcpClients", [...current, config]);
25320
+ if (Object.keys(config.selectedTools).length > 0) {
25321
+ const currentTools = form.getValues("tools") ?? {};
25322
+ const next = { ...currentTools };
25323
+ for (const [name, toolConfig] of Object.entries(config.selectedTools)) {
25324
+ next[name] = { description: toolConfig.description };
25325
+ }
25326
+ form.setValue("tools", next);
25327
+ }
25018
25328
  setIsCreateOpen(false);
25019
25329
  };
25020
25330
  const handleUpdate = (config) => {
25021
25331
  if (viewIndex === null) return;
25022
25332
  const current = form.getValues("mcpClients") ?? [];
25333
+ const oldClient = current[viewIndex];
25334
+ const currentTools = form.getValues("tools") ?? {};
25335
+ const next = { ...currentTools };
25336
+ for (const name of Object.keys(oldClient?.selectedTools ?? {})) {
25337
+ delete next[name];
25338
+ }
25339
+ for (const [name, toolConfig] of Object.entries(config.selectedTools)) {
25340
+ next[name] = { description: toolConfig.description };
25341
+ }
25342
+ form.setValue("tools", next);
25023
25343
  const updated = [...current];
25024
25344
  updated[viewIndex] = { ...updated[viewIndex], ...config };
25025
25345
  form.setValue("mcpClients", updated);
@@ -25028,6 +25348,14 @@ function MCPClientList() {
25028
25348
  const handleRemove = (index) => {
25029
25349
  const current = form.getValues("mcpClients") ?? [];
25030
25350
  const removed = current[index];
25351
+ if (removed?.selectedTools) {
25352
+ const currentTools = form.getValues("tools") ?? {};
25353
+ const next = { ...currentTools };
25354
+ for (const name of Object.keys(removed.selectedTools)) {
25355
+ delete next[name];
25356
+ }
25357
+ form.setValue("tools", next);
25358
+ }
25031
25359
  if (removed?.id) {
25032
25360
  const toDelete = form.getValues("mcpClientsToDelete") ?? [];
25033
25361
  form.setValue("mcpClientsToDelete", [...toDelete, removed.id]);
@@ -25129,8 +25457,9 @@ function MCPClientList() {
25129
25457
  {
25130
25458
  readOnly: isViewingPersisted,
25131
25459
  initialValues: viewFormValues,
25132
- onAdd: isViewingPersisted ? void 0 : handleUpdate,
25133
- submitLabel: isViewingPersisted ? void 0 : "Update MCP Client"
25460
+ initialSelectedTools: viewingClient?.selectedTools,
25461
+ onAdd: readOnly ? void 0 : handleUpdate,
25462
+ submitLabel: isViewingPersisted ? "Update tool selection" : "Update MCP Client"
25134
25463
  }
25135
25464
  )
25136
25465
  ]
@@ -25172,25 +25501,37 @@ function ToolsPage() {
25172
25501
  if (isSet) {
25173
25502
  const next = { ...selectedTools };
25174
25503
  delete next[toolId];
25175
- form.setValue("tools", next);
25504
+ form.setValue("tools", next, { shouldDirty: true });
25176
25505
  } else {
25177
- form.setValue("tools", {
25178
- ...selectedTools,
25179
- [toolId]: { ...selectedTools?.[toolId], description: getOriginalDescription(toolId) }
25180
- });
25506
+ form.setValue(
25507
+ "tools",
25508
+ {
25509
+ ...selectedTools,
25510
+ [toolId]: { ...selectedTools?.[toolId], description: getOriginalDescription(toolId) }
25511
+ },
25512
+ { shouldDirty: true }
25513
+ );
25181
25514
  }
25182
25515
  };
25183
25516
  const handleDescriptionChange = (toolId, description) => {
25184
- form.setValue("tools", {
25185
- ...selectedTools,
25186
- [toolId]: { ...selectedTools?.[toolId], description }
25187
- });
25517
+ form.setValue(
25518
+ "tools",
25519
+ {
25520
+ ...selectedTools,
25521
+ [toolId]: { ...selectedTools?.[toolId], description }
25522
+ },
25523
+ { shouldDirty: true }
25524
+ );
25188
25525
  };
25189
25526
  const handleRulesChange = (toolId, rules) => {
25190
- form.setValue("tools", {
25191
- ...selectedTools,
25192
- [toolId]: { ...selectedTools?.[toolId], rules }
25193
- });
25527
+ form.setValue(
25528
+ "tools",
25529
+ {
25530
+ ...selectedTools,
25531
+ [toolId]: { ...selectedTools?.[toolId], rules }
25532
+ },
25533
+ { shouldDirty: true }
25534
+ );
25194
25535
  };
25195
25536
  const handleIntegrationToolsSubmit = useCallback(
25196
25537
  (providerId, tools2) => {
@@ -25203,7 +25544,7 @@ function ToolsPage() {
25203
25544
  for (const [id, description] of tools2) {
25204
25545
  next[id] = selectedIntegrationTools?.[id] || { description };
25205
25546
  }
25206
- form.setValue("integrationTools", next);
25547
+ form.setValue("integrationTools", next, { shouldDirty: true });
25207
25548
  },
25208
25549
  [form, selectedIntegrationTools]
25209
25550
  );
@@ -25302,25 +25643,37 @@ function AgentsPage() {
25302
25643
  if (isSet) {
25303
25644
  const next = { ...selectedAgents };
25304
25645
  delete next[agentId];
25305
- form.setValue("agents", next);
25646
+ form.setValue("agents", next, { shouldDirty: true });
25306
25647
  } else {
25307
- form.setValue("agents", {
25308
- ...selectedAgents,
25309
- [agentId]: { ...selectedAgents?.[agentId], description: getOriginalDescription(agentId) }
25310
- });
25648
+ form.setValue(
25649
+ "agents",
25650
+ {
25651
+ ...selectedAgents,
25652
+ [agentId]: { ...selectedAgents?.[agentId], description: getOriginalDescription(agentId) }
25653
+ },
25654
+ { shouldDirty: true }
25655
+ );
25311
25656
  }
25312
25657
  };
25313
25658
  const handleDescriptionChange = (agentId, description) => {
25314
- form.setValue("agents", {
25315
- ...selectedAgents,
25316
- [agentId]: { ...selectedAgents?.[agentId], description }
25317
- });
25659
+ form.setValue(
25660
+ "agents",
25661
+ {
25662
+ ...selectedAgents,
25663
+ [agentId]: { ...selectedAgents?.[agentId], description }
25664
+ },
25665
+ { shouldDirty: true }
25666
+ );
25318
25667
  };
25319
25668
  const handleRulesChange = (agentId, rules) => {
25320
- form.setValue("agents", {
25321
- ...selectedAgents,
25322
- [agentId]: { ...selectedAgents?.[agentId], rules }
25323
- });
25669
+ form.setValue(
25670
+ "agents",
25671
+ {
25672
+ ...selectedAgents,
25673
+ [agentId]: { ...selectedAgents?.[agentId], rules }
25674
+ },
25675
+ { shouldDirty: true }
25676
+ );
25324
25677
  };
25325
25678
  const filteredOptions = useMemo(() => {
25326
25679
  return options.filter((option) => option.label.toLowerCase().includes(search.toLowerCase()));
@@ -25404,31 +25757,47 @@ function ScorersPage() {
25404
25757
  if (isSet) {
25405
25758
  const next = { ...selectedScorers };
25406
25759
  delete next[scorerId];
25407
- form.setValue("scorers", next);
25760
+ form.setValue("scorers", next, { shouldDirty: true });
25408
25761
  } else {
25409
- form.setValue("scorers", {
25410
- ...selectedScorers,
25411
- [scorerId]: { ...selectedScorers?.[scorerId], description: getOriginalDescription(scorerId) }
25412
- });
25762
+ form.setValue(
25763
+ "scorers",
25764
+ {
25765
+ ...selectedScorers,
25766
+ [scorerId]: { ...selectedScorers?.[scorerId], description: getOriginalDescription(scorerId) }
25767
+ },
25768
+ { shouldDirty: true }
25769
+ );
25413
25770
  }
25414
25771
  };
25415
25772
  const handleDescriptionChange = (scorerId, description) => {
25416
- form.setValue("scorers", {
25417
- ...selectedScorers,
25418
- [scorerId]: { ...selectedScorers?.[scorerId], description }
25419
- });
25773
+ form.setValue(
25774
+ "scorers",
25775
+ {
25776
+ ...selectedScorers,
25777
+ [scorerId]: { ...selectedScorers?.[scorerId], description }
25778
+ },
25779
+ { shouldDirty: true }
25780
+ );
25420
25781
  };
25421
25782
  const handleSamplingChange = (scorerId, samplingConfig) => {
25422
- form.setValue("scorers", {
25423
- ...selectedScorers,
25424
- [scorerId]: { ...selectedScorers?.[scorerId], sampling: samplingConfig }
25425
- });
25783
+ form.setValue(
25784
+ "scorers",
25785
+ {
25786
+ ...selectedScorers,
25787
+ [scorerId]: { ...selectedScorers?.[scorerId], sampling: samplingConfig }
25788
+ },
25789
+ { shouldDirty: true }
25790
+ );
25426
25791
  };
25427
25792
  const handleRulesChange = (scorerId, rules) => {
25428
- form.setValue("scorers", {
25429
- ...selectedScorers,
25430
- [scorerId]: { ...selectedScorers?.[scorerId], rules }
25431
- });
25793
+ form.setValue(
25794
+ "scorers",
25795
+ {
25796
+ ...selectedScorers,
25797
+ [scorerId]: { ...selectedScorers?.[scorerId], rules }
25798
+ },
25799
+ { shouldDirty: true }
25800
+ );
25432
25801
  };
25433
25802
  const filteredOptions = useMemo(() => {
25434
25803
  return options.filter((option) => option.label.toLowerCase().includes(search.toLowerCase()));
@@ -25572,25 +25941,37 @@ function WorkflowsPage() {
25572
25941
  if (isSet) {
25573
25942
  const next = { ...selectedWorkflows };
25574
25943
  delete next[workflowId];
25575
- form.setValue("workflows", next);
25944
+ form.setValue("workflows", next, { shouldDirty: true });
25576
25945
  } else {
25577
- form.setValue("workflows", {
25578
- ...selectedWorkflows,
25579
- [workflowId]: { ...selectedWorkflows?.[workflowId], description: getOriginalDescription(workflowId) }
25580
- });
25946
+ form.setValue(
25947
+ "workflows",
25948
+ {
25949
+ ...selectedWorkflows,
25950
+ [workflowId]: { ...selectedWorkflows?.[workflowId], description: getOriginalDescription(workflowId) }
25951
+ },
25952
+ { shouldDirty: true }
25953
+ );
25581
25954
  }
25582
25955
  };
25583
25956
  const handleDescriptionChange = (workflowId, description) => {
25584
- form.setValue("workflows", {
25585
- ...selectedWorkflows,
25586
- [workflowId]: { ...selectedWorkflows?.[workflowId], description }
25587
- });
25957
+ form.setValue(
25958
+ "workflows",
25959
+ {
25960
+ ...selectedWorkflows,
25961
+ [workflowId]: { ...selectedWorkflows?.[workflowId], description }
25962
+ },
25963
+ { shouldDirty: true }
25964
+ );
25588
25965
  };
25589
25966
  const handleRulesChange = (workflowId, rules) => {
25590
- form.setValue("workflows", {
25591
- ...selectedWorkflows,
25592
- [workflowId]: { ...selectedWorkflows?.[workflowId], rules }
25593
- });
25967
+ form.setValue(
25968
+ "workflows",
25969
+ {
25970
+ ...selectedWorkflows,
25971
+ [workflowId]: { ...selectedWorkflows?.[workflowId], rules }
25972
+ },
25973
+ { shouldDirty: true }
25974
+ );
25594
25975
  };
25595
25976
  const filteredOptions = useMemo(() => {
25596
25977
  return options.filter((option) => option.label.toLowerCase().includes(search.toLowerCase()));
@@ -25687,22 +26068,45 @@ function MemoryPage() {
25687
26068
  }
25688
26069
  ) }),
25689
26070
  isEnabled && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
26071
+ /* @__PURE__ */ jsx(ObservationalMemoryEntity, {}),
25690
26072
  /* @__PURE__ */ jsx(LastMessagesEntity, {}),
25691
26073
  /* @__PURE__ */ jsx(SemanticRecallEntity, {}),
25692
- /* @__PURE__ */ jsx(ReadOnlyEntity, {}),
25693
- /* @__PURE__ */ jsx(ObservationalMemoryEntity, {})
26074
+ /* @__PURE__ */ jsx(ReadOnlyEntity, {})
25694
26075
  ] })
25695
26076
  ] }) });
25696
26077
  }
25697
26078
  function LastMessagesEntity() {
25698
26079
  const { form, readOnly } = useAgentEditFormContext();
25699
26080
  const { control } = form;
26081
+ const lastMessages = useWatch({ control, name: "memory.lastMessages" });
26082
+ const lastMessagesEnabled = lastMessages !== false;
25700
26083
  return /* @__PURE__ */ jsxs(Entity, { className: "flex-col gap-0 p-0 overflow-hidden", children: [
25701
- /* @__PURE__ */ jsx("div", { className: "flex gap-3 py-3 px-4", children: /* @__PURE__ */ jsxs(EntityContent, { children: [
25702
- /* @__PURE__ */ jsx(EntityName, { children: "Last Messages" }),
25703
- /* @__PURE__ */ jsx(EntityDescription, { children: "Number of recent messages to include in context" })
25704
- ] }) }),
25705
- /* @__PURE__ */ jsx("div", { className: "bg-surface2 border-t border-border1 p-4", children: /* @__PURE__ */ jsx(
26084
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3 py-3 px-4", children: [
26085
+ /* @__PURE__ */ jsxs(EntityContent, { children: [
26086
+ /* @__PURE__ */ jsx(EntityName, { children: "Message History" }),
26087
+ /* @__PURE__ */ jsx(EntityDescription, { children: "Number of recent messages to include in context" })
26088
+ ] }),
26089
+ !readOnly && /* @__PURE__ */ jsx(
26090
+ Controller,
26091
+ {
26092
+ name: "memory.lastMessages",
26093
+ control,
26094
+ render: ({ field }) => /* @__PURE__ */ jsx(
26095
+ Switch,
26096
+ {
26097
+ checked: lastMessagesEnabled,
26098
+ onCheckedChange: (checked) => {
26099
+ field.onChange(checked ? 40 : false);
26100
+ if (checked) {
26101
+ form.setValue("memory.observationalMemory.enabled", false, { shouldDirty: true });
26102
+ }
26103
+ }
26104
+ }
26105
+ )
26106
+ }
26107
+ )
26108
+ ] }),
26109
+ lastMessagesEnabled && /* @__PURE__ */ jsx("div", { className: "bg-surface2 border-t border-border1 p-4", children: /* @__PURE__ */ jsx(
25706
26110
  Controller,
25707
26111
  {
25708
26112
  name: "memory.lastMessages",
@@ -25823,7 +26227,18 @@ function ObservationalMemoryEntity() {
25823
26227
  {
25824
26228
  name: "memory.observationalMemory.enabled",
25825
26229
  control,
25826
- render: ({ field }) => /* @__PURE__ */ jsx(Switch, { checked: field.value ?? false, onCheckedChange: field.onChange })
26230
+ render: ({ field }) => /* @__PURE__ */ jsx(
26231
+ Switch,
26232
+ {
26233
+ checked: field.value ?? false,
26234
+ onCheckedChange: (checked) => {
26235
+ field.onChange(checked);
26236
+ if (checked) {
26237
+ form.setValue("memory.lastMessages", false, { shouldDirty: true });
26238
+ }
26239
+ }
26240
+ }
26241
+ )
25827
26242
  }
25828
26243
  )
25829
26244
  ] }),
@@ -25852,7 +26267,7 @@ function ObservationalMemoryFields() {
25852
26267
  value: field.value ?? "",
25853
26268
  onValueChange: (v) => {
25854
26269
  field.onChange(v);
25855
- setValue("memory.observationalMemory.model.name", "");
26270
+ setValue("memory.observationalMemory.model.name", "", { shouldDirty: true });
25856
26271
  },
25857
26272
  variant: "light"
25858
26273
  }
@@ -25943,7 +26358,7 @@ function ObserverFields({ observerProvider }) {
25943
26358
  value: field.value ?? "",
25944
26359
  onValueChange: (v) => {
25945
26360
  field.onChange(v);
25946
- setValue("memory.observationalMemory.observation.model.name", "");
26361
+ setValue("memory.observationalMemory.observation.model.name", "", { shouldDirty: true });
25947
26362
  },
25948
26363
  variant: "light"
25949
26364
  }
@@ -26140,7 +26555,7 @@ function ReflectorFields({ reflectorProvider }) {
26140
26555
  value: field.value ?? "",
26141
26556
  onValueChange: (v) => {
26142
26557
  field.onChange(v);
26143
- setValue("memory.observationalMemory.reflection.model.name", "");
26558
+ setValue("memory.observationalMemory.reflection.model.name", "", { shouldDirty: true });
26144
26559
  },
26145
26560
  variant: "light"
26146
26561
  }
@@ -26809,118 +27224,1466 @@ function VariablesPage() {
26809
27224
  ] }) });
26810
27225
  }
26811
27226
 
26812
- const arrayToRecord = (arr) => {
26813
- const record = {};
26814
- for (const id of arr) {
26815
- record[id] = { description: void 0 };
26816
- }
26817
- return record;
27227
+ function useStoredSkills() {
27228
+ const client = useMastraClient();
27229
+ return useQuery({
27230
+ queryKey: ["stored-skills"],
27231
+ queryFn: () => client.listStoredSkills()
27232
+ });
27233
+ }
27234
+
27235
+ const useWorkspaceInfo = (workspaceId) => {
27236
+ const client = useMastraClient();
27237
+ return useQuery({
27238
+ queryKey: ["workspace", "info", workspaceId],
27239
+ queryFn: async () => {
27240
+ if (!isWorkspaceV1Supported(client)) {
27241
+ throw new Error("Workspace v1 not supported by core or client");
27242
+ }
27243
+ if (!workspaceId) {
27244
+ throw new Error("workspaceId is required");
27245
+ }
27246
+ const workspace = client.getWorkspace(workspaceId);
27247
+ return workspace.info();
27248
+ },
27249
+ enabled: !!workspaceId && isWorkspaceV1Supported(client),
27250
+ retry: shouldRetryWorkspaceQuery
27251
+ });
26818
27252
  };
26819
- const normalizeToolsToRecord = (tools) => {
26820
- if (!tools) return {};
26821
- if (!Array.isArray(tools)) return { ...tools };
26822
- const result = {};
26823
- for (const item of tools) {
26824
- if (typeof item === "string") {
26825
- result[item] = { description: void 0 };
26826
- } else {
26827
- Object.assign(result, item.value);
26828
- }
26829
- }
26830
- return result;
27253
+ const useWorkspaces = () => {
27254
+ const client = useMastraClient();
27255
+ return useQuery({
27256
+ queryKey: ["workspaces"],
27257
+ queryFn: async () => {
27258
+ if (!isWorkspaceV1Supported(client)) {
27259
+ throw new Error("Workspace v1 not supported by core or client");
27260
+ }
27261
+ return client.listWorkspaces();
27262
+ },
27263
+ retry: shouldRetryWorkspaceQuery
27264
+ });
26831
27265
  };
26832
- const splitModelId = (id) => {
26833
- if (!id) return void 0;
26834
- const [p, ...rest] = id.split("/");
26835
- const n = rest.join("/");
26836
- return p && n ? { provider: p, name: n } : void 0;
27266
+ const useWorkspaceFiles = (path, options) => {
27267
+ const client = useMastraClient();
27268
+ return useQuery({
27269
+ queryKey: ["workspace", "files", path, options?.recursive, options?.workspaceId],
27270
+ queryFn: async () => {
27271
+ if (!isWorkspaceV1Supported(client)) {
27272
+ throw new Error("Workspace v1 not supported by core or client");
27273
+ }
27274
+ if (!options?.workspaceId) {
27275
+ throw new Error("workspaceId is required");
27276
+ }
27277
+ const workspace = client.getWorkspace(options.workspaceId);
27278
+ return workspace.listFiles(path, options?.recursive);
27279
+ },
27280
+ enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
27281
+ retry: shouldRetryWorkspaceQuery
27282
+ });
26837
27283
  };
26838
- const joinModelId = (m) => m?.provider && m?.name ? `${m.provider}/${m.name}` : void 0;
26839
- const transformIntegrationToolsForApi = (integrationTools) => {
26840
- if (!integrationTools || Object.keys(integrationTools).length === 0) return void 0;
26841
- const result = {};
26842
- for (const [compositeKey, config] of Object.entries(integrationTools)) {
26843
- const separatorIndex = compositeKey.indexOf(":");
26844
- if (separatorIndex === -1) continue;
26845
- const providerId = compositeKey.slice(0, separatorIndex);
26846
- const toolSlug = compositeKey.slice(separatorIndex + 1);
26847
- if (!result[providerId]) {
26848
- result[providerId] = { tools: {} };
26849
- }
26850
- result[providerId].tools[toolSlug] = { description: config.description, rules: config.rules };
26851
- }
26852
- return result;
27284
+ const useWorkspaceFile = (path, options) => {
27285
+ const client = useMastraClient();
27286
+ return useQuery({
27287
+ queryKey: ["workspace", "file", path, options?.workspaceId],
27288
+ queryFn: async () => {
27289
+ if (!isWorkspaceV1Supported(client)) {
27290
+ throw new Error("Workspace v1 not supported by core or client");
27291
+ }
27292
+ if (!options?.workspaceId) {
27293
+ throw new Error("workspaceId is required");
27294
+ }
27295
+ const workspace = client.getWorkspace(options.workspaceId);
27296
+ return workspace.readFile(path, options?.encoding);
27297
+ },
27298
+ enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
27299
+ retry: shouldRetryWorkspaceQuery
27300
+ });
26853
27301
  };
26854
- const normalizeIntegrationToolsToRecord = (integrationTools) => {
26855
- if (!integrationTools) return {};
26856
- const result = {};
26857
- for (const [providerId, providerConfig] of Object.entries(integrationTools)) {
26858
- if (providerConfig.tools) {
26859
- for (const [toolSlug, toolConfig] of Object.entries(providerConfig.tools)) {
26860
- result[`${providerId}:${toolSlug}`] = { description: toolConfig.description, rules: toolConfig.rules };
27302
+ const useWorkspaceFileStat = (path, options) => {
27303
+ const client = useMastraClient();
27304
+ return useQuery({
27305
+ queryKey: ["workspace", "stat", path, options?.workspaceId],
27306
+ queryFn: async () => {
27307
+ if (!isWorkspaceV1Supported(client)) {
27308
+ throw new Error("Workspace v1 not supported by core or client");
27309
+ }
27310
+ if (!options?.workspaceId) {
27311
+ throw new Error("workspaceId is required");
27312
+ }
27313
+ const workspace = client.getWorkspace(options.workspaceId);
27314
+ return workspace.stat(path);
27315
+ },
27316
+ enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
27317
+ retry: shouldRetryWorkspaceQuery
27318
+ });
27319
+ };
27320
+ const useWriteWorkspaceFile = () => {
27321
+ const client = useMastraClient();
27322
+ const queryClient = useQueryClient();
27323
+ return useMutation({
27324
+ mutationFn: async (params) => {
27325
+ if (!isWorkspaceV1Supported(client)) {
27326
+ throw new Error("Workspace v1 not supported by core or client");
26861
27327
  }
27328
+ const workspace = client.getWorkspace(params.workspaceId);
27329
+ return workspace.writeFile(params.path, params.content, {
27330
+ encoding: params.encoding,
27331
+ recursive: params.recursive ?? true
27332
+ });
27333
+ },
27334
+ onSuccess: (_, variables) => {
27335
+ const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
27336
+ queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
27337
+ queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
26862
27338
  }
26863
- }
26864
- return result;
27339
+ });
26865
27340
  };
26866
- const mapInstructionBlocksToApi = (blocks) => (blocks ?? []).map((block) => ({
26867
- type: block.type,
26868
- content: block.content,
26869
- rules: block.rules
26870
- }));
26871
- const mapInstructionBlocksFromApi = (instructionsRaw) => {
26872
- const instructionsString = Array.isArray(instructionsRaw) ? instructionsRaw.map((b) => b.type === "prompt_block" ? b.content : "").filter(Boolean).join("\n\n") : instructionsRaw || "";
26873
- const instructionBlocks = Array.isArray(instructionsRaw) ? instructionsRaw.filter(
26874
- (b) => b.type === "prompt_block"
26875
- ).map((b) => createInstructionBlock(b.content, b.rules)) : [createInstructionBlock(instructionsRaw || "")];
26876
- return { instructionsString, instructionBlocks };
27341
+ const useWriteWorkspaceFileFromFile = () => {
27342
+ const client = useMastraClient();
27343
+ const queryClient = useQueryClient();
27344
+ return useMutation({
27345
+ mutationFn: async (params) => {
27346
+ if (!isWorkspaceV1Supported(client)) {
27347
+ throw new Error("Workspace v1 not supported by core or client");
27348
+ }
27349
+ const arrayBuffer = await params.file.arrayBuffer();
27350
+ const base64 = btoa(new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), ""));
27351
+ const workspace = client.getWorkspace(params.workspaceId);
27352
+ return workspace.writeFile(params.path, base64, {
27353
+ encoding: "base64",
27354
+ recursive: params.recursive ?? true
27355
+ });
27356
+ },
27357
+ onSuccess: (_, variables) => {
27358
+ const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
27359
+ queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
27360
+ queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
27361
+ }
27362
+ });
26877
27363
  };
26878
- const mapScorersToApi = (scorers) => {
26879
- const entries = scorers ? Object.entries(scorers) : void 0;
26880
- if (!entries) return void 0;
26881
- return Object.fromEntries(
26882
- entries.map(([key, value]) => [
26883
- key,
26884
- {
26885
- description: value.description,
26886
- sampling: value.sampling ? {
26887
- type: value.sampling.type,
26888
- rate: value.sampling.rate || 0
26889
- } : void 0,
26890
- rules: value.rules
27364
+ const useDeleteWorkspaceFile = () => {
27365
+ const client = useMastraClient();
27366
+ const queryClient = useQueryClient();
27367
+ return useMutation({
27368
+ mutationFn: async (params) => {
27369
+ if (!isWorkspaceV1Supported(client)) {
27370
+ throw new Error("Workspace v1 not supported by core or client");
26891
27371
  }
26892
- ])
26893
- );
27372
+ const workspace = client.getWorkspace(params.workspaceId);
27373
+ return workspace.delete(params.path, {
27374
+ recursive: params.recursive,
27375
+ force: params.force
27376
+ });
27377
+ },
27378
+ onSuccess: (_, variables) => {
27379
+ const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
27380
+ queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
27381
+ queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
27382
+ }
27383
+ });
26894
27384
  };
26895
- const normalizeScorersFromApi = (scorers) => {
26896
- if (!scorers) return {};
26897
- let record;
26898
- if (Array.isArray(scorers)) {
26899
- record = {};
26900
- for (const variant of scorers) {
26901
- Object.assign(record, variant.value);
27385
+ const useCreateWorkspaceDirectory = () => {
27386
+ const client = useMastraClient();
27387
+ const queryClient = useQueryClient();
27388
+ return useMutation({
27389
+ mutationFn: async (params) => {
27390
+ if (!isWorkspaceV1Supported(client)) {
27391
+ throw new Error("Workspace v1 not supported by core or client");
27392
+ }
27393
+ const workspace = client.getWorkspace(params.workspaceId);
27394
+ return workspace.mkdir(params.path, params.recursive);
27395
+ },
27396
+ onSuccess: (_, variables) => {
27397
+ const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
27398
+ queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
26902
27399
  }
26903
- } else {
26904
- record = scorers;
26905
- }
26906
- const result = {};
26907
- for (const [key, value] of Object.entries(record)) {
26908
- result[key] = {
26909
- description: value.description,
26910
- sampling: value.sampling?.type === "ratio" ? { type: "ratio", rate: value.sampling.rate } : void 0,
26911
- rules: value.rules
26912
- };
26913
- }
26914
- return result;
27400
+ });
26915
27401
  };
26916
- const buildObservationalMemoryForApi = (om) => {
26917
- if (!om?.enabled) return void 0;
26918
- const modelId = joinModelId(om.model);
26919
- const obsModelId = joinModelId(om.observation?.model);
26920
- const observation = obsModelId || om.observation?.messageTokens || om.observation?.maxTokensPerBatch || om.observation?.bufferTokens !== void 0 || om.observation?.bufferActivation !== void 0 || om.observation?.blockAfter !== void 0 ? {
26921
- model: obsModelId,
26922
- messageTokens: om.observation?.messageTokens,
26923
- maxTokensPerBatch: om.observation?.maxTokensPerBatch,
27402
+ const useSearchWorkspace = () => {
27403
+ const client = useMastraClient();
27404
+ return useMutation({
27405
+ mutationFn: async (params) => {
27406
+ if (!isWorkspaceV1Supported(client)) {
27407
+ throw new Error("Workspace v1 not supported by core or client");
27408
+ }
27409
+ const workspace = client.getWorkspace(params.workspaceId);
27410
+ return workspace.search({
27411
+ query: params.query,
27412
+ topK: params.topK,
27413
+ mode: params.mode,
27414
+ minScore: params.minScore
27415
+ });
27416
+ }
27417
+ });
27418
+ };
27419
+ const useIndexWorkspaceContent = () => {
27420
+ const client = useMastraClient();
27421
+ return useMutation({
27422
+ mutationFn: async (params) => {
27423
+ if (!isWorkspaceV1Supported(client)) {
27424
+ throw new Error("Workspace v1 not supported by core or client");
27425
+ }
27426
+ const workspace = client.getWorkspace(params.workspaceId);
27427
+ return workspace.index({
27428
+ path: params.path,
27429
+ content: params.content,
27430
+ metadata: params.metadata
27431
+ });
27432
+ }
27433
+ });
27434
+ };
27435
+
27436
+ const useWorkspaceSkills = (options) => {
27437
+ const client = useMastraClient();
27438
+ return useQuery({
27439
+ queryKey: ["workspace", "skills", options?.workspaceId],
27440
+ queryFn: async () => {
27441
+ if (!isWorkspaceV1Supported(client)) {
27442
+ throw new Error("Workspace v1 not supported by core or client");
27443
+ }
27444
+ if (!options?.workspaceId) {
27445
+ throw new Error("workspaceId is required");
27446
+ }
27447
+ const workspace = client.getWorkspace(options.workspaceId);
27448
+ return workspace.listSkills();
27449
+ },
27450
+ enabled: !!options?.workspaceId && isWorkspaceV1Supported(client),
27451
+ retry: shouldRetryWorkspaceQuery
27452
+ });
27453
+ };
27454
+ const useWorkspaceSkill = (skillName, options) => {
27455
+ const client = useMastraClient();
27456
+ return useQuery({
27457
+ queryKey: ["workspace", "skills", skillName, options?.workspaceId],
27458
+ queryFn: async () => {
27459
+ if (!isWorkspaceV1Supported(client)) {
27460
+ throw new Error("Workspace v1 not supported by core or client");
27461
+ }
27462
+ if (!options?.workspaceId) {
27463
+ throw new Error("workspaceId is required");
27464
+ }
27465
+ const workspace = client.getWorkspace(options.workspaceId);
27466
+ const skill = workspace.getSkill(skillName);
27467
+ return skill.details();
27468
+ },
27469
+ enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
27470
+ retry: shouldRetryWorkspaceQuery
27471
+ });
27472
+ };
27473
+ const useWorkspaceSkillReferences = (skillName, options) => {
27474
+ const client = useMastraClient();
27475
+ return useQuery({
27476
+ queryKey: ["workspace", "skills", skillName, "references", options?.workspaceId],
27477
+ queryFn: async () => {
27478
+ if (!isWorkspaceV1Supported(client)) {
27479
+ throw new Error("Workspace v1 not supported by core or client");
27480
+ }
27481
+ if (!options?.workspaceId) {
27482
+ throw new Error("workspaceId is required");
27483
+ }
27484
+ const workspace = client.getWorkspace(options.workspaceId);
27485
+ const skill = workspace.getSkill(skillName);
27486
+ return skill.listReferences();
27487
+ },
27488
+ enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
27489
+ retry: shouldRetryWorkspaceQuery
27490
+ });
27491
+ };
27492
+ const useWorkspaceSkillReference = (skillName, referencePath, options) => {
27493
+ const client = useMastraClient();
27494
+ return useQuery({
27495
+ queryKey: ["workspace", "skills", skillName, "references", referencePath, options?.workspaceId],
27496
+ queryFn: async () => {
27497
+ if (!isWorkspaceV1Supported(client)) {
27498
+ throw new Error("Workspace v1 not supported by core or client");
27499
+ }
27500
+ if (!options?.workspaceId) {
27501
+ throw new Error("workspaceId is required");
27502
+ }
27503
+ const workspace = client.getWorkspace(options.workspaceId);
27504
+ const skill = workspace.getSkill(skillName);
27505
+ return skill.getReference(referencePath);
27506
+ },
27507
+ enabled: options?.enabled !== false && !!skillName && !!referencePath && !!options?.workspaceId && isWorkspaceV1Supported(client),
27508
+ retry: shouldRetryWorkspaceQuery
27509
+ });
27510
+ };
27511
+ const useSearchWorkspaceSkills = () => {
27512
+ const client = useMastraClient();
27513
+ return useMutation({
27514
+ mutationFn: async (params) => {
27515
+ if (!isWorkspaceV1Supported(client)) {
27516
+ throw new Error("Workspace v1 not supported by core or client");
27517
+ }
27518
+ const workspace = client.getWorkspace(params.workspaceId);
27519
+ return workspace.searchSkills(params);
27520
+ }
27521
+ });
27522
+ };
27523
+ const useAgentSkill = (agentId, skillName, options) => {
27524
+ const client = useMastraClient();
27525
+ return useQuery({
27526
+ queryKey: ["agents", agentId, "skills", skillName, options?.workspaceId],
27527
+ queryFn: async () => {
27528
+ if (!isWorkspaceV1Supported(client)) {
27529
+ throw new Error("Workspace v1 not supported by core or client");
27530
+ }
27531
+ if (!options?.workspaceId) {
27532
+ throw new Error("workspaceId is required");
27533
+ }
27534
+ const workspace = client.getWorkspace(options.workspaceId);
27535
+ const skill = workspace.getSkill(skillName);
27536
+ return skill.details();
27537
+ },
27538
+ enabled: options?.enabled !== false && !!agentId && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
27539
+ retry: shouldRetryWorkspaceQuery
27540
+ });
27541
+ };
27542
+
27543
+ const useSearchSkillsSh = (workspaceId) => {
27544
+ const client = useMastraClient();
27545
+ return useMutation({
27546
+ mutationFn: async (query) => {
27547
+ if (!workspaceId) {
27548
+ throw new Error("Workspace ID is required");
27549
+ }
27550
+ const baseUrl = client.options.baseUrl || "";
27551
+ const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/search?q=${encodeURIComponent(query)}&limit=10`;
27552
+ const response = await fetch(url);
27553
+ if (!response.ok) {
27554
+ throw new Error(`Failed to search skills: ${response.statusText}`);
27555
+ }
27556
+ return response.json().catch(() => {
27557
+ throw new Error("Invalid response from server");
27558
+ });
27559
+ }
27560
+ });
27561
+ };
27562
+ const usePopularSkillsSh = (workspaceId) => {
27563
+ const client = useMastraClient();
27564
+ return useQuery({
27565
+ queryKey: ["skills-sh", "popular", workspaceId],
27566
+ queryFn: async () => {
27567
+ if (!workspaceId) {
27568
+ throw new Error("Workspace ID is required");
27569
+ }
27570
+ const baseUrl = client.options.baseUrl || "";
27571
+ const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/popular?limit=10&offset=0`;
27572
+ const response = await fetch(url);
27573
+ if (!response.ok) {
27574
+ throw new Error(`Failed to fetch popular skills: ${response.statusText}`);
27575
+ }
27576
+ return response.json().catch(() => {
27577
+ throw new Error("Invalid response from server");
27578
+ });
27579
+ },
27580
+ staleTime: 5 * 60 * 1e3,
27581
+ // 5 minutes
27582
+ enabled: !!workspaceId
27583
+ });
27584
+ };
27585
+ const useSkillPreview = (workspaceId, owner, repo, skillPath, options) => {
27586
+ const client = useMastraClient();
27587
+ return useQuery({
27588
+ queryKey: ["skills-sh", "preview", workspaceId, owner, repo, skillPath],
27589
+ queryFn: async () => {
27590
+ if (!workspaceId || !owner || !repo || !skillPath) {
27591
+ throw new Error("workspaceId, owner, repo, and skillPath are required");
27592
+ }
27593
+ const baseUrl = client.options.baseUrl || "";
27594
+ const params = new URLSearchParams({ owner, repo, path: skillPath });
27595
+ const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/preview?${params}`;
27596
+ const response = await fetch(url);
27597
+ if (!response.ok) {
27598
+ throw new Error(`Failed to fetch preview: ${response.statusText}`);
27599
+ }
27600
+ const data = await response.json().catch(() => {
27601
+ throw new Error("Invalid response from server");
27602
+ });
27603
+ return data.content;
27604
+ },
27605
+ enabled: options?.enabled !== false && !!workspaceId && !!owner && !!repo && !!skillPath,
27606
+ retry: false
27607
+ });
27608
+ };
27609
+ const useInstallSkill = () => {
27610
+ const client = useMastraClient();
27611
+ const queryClient = useQueryClient();
27612
+ return useMutation({
27613
+ mutationFn: async (params) => {
27614
+ const [owner, repo] = params.repository.split("/");
27615
+ if (!owner || !repo) {
27616
+ throw new Error("Invalid repository format. Expected owner/repo");
27617
+ }
27618
+ const baseUrl = client.options.baseUrl || "";
27619
+ const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/install`;
27620
+ const body = { owner, repo, skillName: params.skillName };
27621
+ if (params.mount) {
27622
+ body.mount = params.mount;
27623
+ }
27624
+ const response = await fetch(url, {
27625
+ method: "POST",
27626
+ headers: { "Content-Type": "application/json" },
27627
+ body: JSON.stringify(body)
27628
+ });
27629
+ if (!response.ok) {
27630
+ const error = await response.json().catch(() => ({}));
27631
+ throw new Error(error.error || error.message || `Failed to install skill: ${response.statusText}`);
27632
+ }
27633
+ return response.json().catch(() => {
27634
+ throw new Error("Invalid response from server");
27635
+ });
27636
+ },
27637
+ onSuccess: (_, variables) => {
27638
+ queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
27639
+ }
27640
+ });
27641
+ };
27642
+ const useUpdateSkills = () => {
27643
+ const client = useMastraClient();
27644
+ const queryClient = useQueryClient();
27645
+ return useMutation({
27646
+ mutationFn: async (params) => {
27647
+ const baseUrl = client.options.baseUrl || "";
27648
+ const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/update`;
27649
+ const response = await fetch(url, {
27650
+ method: "POST",
27651
+ headers: { "Content-Type": "application/json" },
27652
+ body: JSON.stringify({ skillName: params.skillName })
27653
+ });
27654
+ if (!response.ok) {
27655
+ const error = await response.json().catch(() => ({}));
27656
+ throw new Error(error.error || error.message || `Failed to update skill: ${response.statusText}`);
27657
+ }
27658
+ return response.json().catch(() => {
27659
+ throw new Error("Invalid response from server");
27660
+ });
27661
+ },
27662
+ onSuccess: (_, variables) => {
27663
+ queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
27664
+ }
27665
+ });
27666
+ };
27667
+ const useRemoveSkill = () => {
27668
+ const client = useMastraClient();
27669
+ const queryClient = useQueryClient();
27670
+ return useMutation({
27671
+ mutationFn: async (params) => {
27672
+ const baseUrl = client.options.baseUrl || "";
27673
+ const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/remove`;
27674
+ const response = await fetch(url, {
27675
+ method: "POST",
27676
+ headers: { "Content-Type": "application/json" },
27677
+ body: JSON.stringify({ skillName: params.skillName })
27678
+ });
27679
+ if (!response.ok) {
27680
+ const error = await response.json().catch(() => ({}));
27681
+ throw new Error(error.error || error.message || `Failed to remove skill: ${response.statusText}`);
27682
+ }
27683
+ return response.json().catch(() => {
27684
+ throw new Error("Invalid response from server");
27685
+ });
27686
+ },
27687
+ onSuccess: (_, variables) => {
27688
+ queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
27689
+ }
27690
+ });
27691
+ };
27692
+ function parseSkillSource(topSource, skillName) {
27693
+ let cleanSource = topSource.replace(/^https?:\/\//, "");
27694
+ cleanSource = cleanSource.replace(/^github\.com\//, "");
27695
+ cleanSource = cleanSource.replace(/\/$/, "");
27696
+ const parts = cleanSource.split("/").filter(Boolean);
27697
+ if (parts.length < 2) {
27698
+ return null;
27699
+ }
27700
+ const owner = parts[0];
27701
+ const repo = parts[1];
27702
+ let skillPath;
27703
+ if (parts.length > 2) {
27704
+ skillPath = parts.slice(2).join("/");
27705
+ } else if (skillName) {
27706
+ skillPath = skillName;
27707
+ } else {
27708
+ return null;
27709
+ }
27710
+ return {
27711
+ owner,
27712
+ repo,
27713
+ skillPath
27714
+ };
27715
+ }
27716
+
27717
+ const TreeContext = React.createContext(null);
27718
+ function TreeProvider({ children, value }) {
27719
+ return /* @__PURE__ */ jsx(TreeContext.Provider, { value, children });
27720
+ }
27721
+ function useTreeContext() {
27722
+ return React.useContext(TreeContext);
27723
+ }
27724
+ const TreeDepthContext = React.createContext(0);
27725
+ function TreeDepthProvider({ children, depth }) {
27726
+ return /* @__PURE__ */ jsx(TreeDepthContext.Provider, { value: depth, children });
27727
+ }
27728
+ function useTreeDepth() {
27729
+ return React.useContext(TreeDepthContext);
27730
+ }
27731
+
27732
+ const TreeRoot = React.forwardRef(
27733
+ ({ selectedId, onSelect, className, children }, ref) => {
27734
+ const contextValue = React.useMemo(() => ({ selectedId, onSelect }), [selectedId, onSelect]);
27735
+ return /* @__PURE__ */ jsx(TreeProvider, { value: contextValue, children: /* @__PURE__ */ jsx(TreeDepthProvider, { depth: 0, children: /* @__PURE__ */ jsx("ul", { ref, role: "tree", className: cn("flex flex-col text-xs", className), children }) }) });
27736
+ }
27737
+ );
27738
+ TreeRoot.displayName = "Tree";
27739
+
27740
+ const TreeFolder = React.forwardRef(
27741
+ ({ defaultOpen, open, onOpenChange, className, children }, ref) => {
27742
+ return /* @__PURE__ */ jsx("li", { ref, role: "treeitem", className: cn("flex flex-col", className), children: /* @__PURE__ */ jsx(Collapsible, { defaultOpen, open, onOpenChange, children }) });
27743
+ }
27744
+ );
27745
+ TreeFolder.displayName = "Tree.Folder";
27746
+
27747
+ const TreeFolderTrigger = React.forwardRef(
27748
+ ({ className, children, actions }, ref) => {
27749
+ const depth = useTreeDepth();
27750
+ return /* @__PURE__ */ jsxs(
27751
+ "div",
27752
+ {
27753
+ ref,
27754
+ className: cn(
27755
+ "group flex h-7 min-w-0 w-full items-center rounded-sm hover:bg-surface4",
27756
+ transitions.colors,
27757
+ className
27758
+ ),
27759
+ children: [
27760
+ /* @__PURE__ */ jsxs(
27761
+ CollapsibleTrigger,
27762
+ {
27763
+ className: cn(
27764
+ "flex h-7 min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-sm px-1",
27765
+ focusRing.visible
27766
+ ),
27767
+ style: { paddingLeft: depth * 12 },
27768
+ children: [
27769
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-3 shrink-0 text-neutral3" }),
27770
+ children
27771
+ ]
27772
+ }
27773
+ ),
27774
+ actions && /* @__PURE__ */ jsx("span", { className: "shrink-0 pr-1", onClick: (e) => e.stopPropagation(), children: actions })
27775
+ ]
27776
+ }
27777
+ );
27778
+ }
27779
+ );
27780
+ TreeFolderTrigger.displayName = "Tree.FolderTrigger";
27781
+
27782
+ const TreeFolderContent = React.forwardRef(
27783
+ ({ className, children }, ref) => {
27784
+ const depth = useTreeDepth();
27785
+ return /* @__PURE__ */ jsx(CollapsibleContent, { ref, className: cn(className), children: /* @__PURE__ */ jsx(TreeDepthProvider, { depth: depth + 1, children: /* @__PURE__ */ jsx("ul", { role: "group", className: "flex flex-col", children }) }) });
27786
+ }
27787
+ );
27788
+ TreeFolderContent.displayName = "Tree.FolderContent";
27789
+
27790
+ const TreeFile = React.forwardRef(({ id, className, children }, ref) => {
27791
+ const treeCtx = useTreeContext();
27792
+ const depth = useTreeDepth();
27793
+ const isSelected = id != null && treeCtx?.selectedId === id;
27794
+ const handleClick = () => {
27795
+ if (id != null && treeCtx?.onSelect) {
27796
+ treeCtx.onSelect(id);
27797
+ }
27798
+ };
27799
+ const handleKeyDown = (e) => {
27800
+ if ((e.key === "Enter" || e.key === " ") && id != null && treeCtx?.onSelect) {
27801
+ e.preventDefault();
27802
+ treeCtx.onSelect(id);
27803
+ }
27804
+ };
27805
+ return /* @__PURE__ */ jsx(
27806
+ "li",
27807
+ {
27808
+ ref,
27809
+ role: "treeitem",
27810
+ "aria-selected": isSelected || void 0,
27811
+ tabIndex: 0,
27812
+ className: cn(
27813
+ "group flex h-7 min-w-0 cursor-pointer items-center gap-1.5 rounded-sm px-1",
27814
+ transitions.colors,
27815
+ focusRing.visible,
27816
+ "hover:bg-surface4",
27817
+ isSelected && "bg-surface4 text-neutral6",
27818
+ className
27819
+ ),
27820
+ style: { paddingLeft: depth * 12 + 18 },
27821
+ onClick: handleClick,
27822
+ onKeyDown: handleKeyDown,
27823
+ children
27824
+ }
27825
+ );
27826
+ });
27827
+ TreeFile.displayName = "Tree.File";
27828
+
27829
+ const TreeIcon = React.forwardRef(({ className, children }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn("flex shrink-0 items-center [&>svg]:size-3.5", className), children }));
27830
+ TreeIcon.displayName = "Tree.Icon";
27831
+
27832
+ const TreeLabel = React.forwardRef(({ className, children }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn("truncate text-neutral5", className), children }));
27833
+ TreeLabel.displayName = "Tree.Label";
27834
+
27835
+ const TreeInput = React.forwardRef(
27836
+ ({ type, onSubmit, onCancel, defaultValue = "", placeholder, autoFocus = true, className }, ref) => {
27837
+ const depth = useTreeDepth();
27838
+ const inputRef = React.useRef(null);
27839
+ const submittedRef = React.useRef(false);
27840
+ const handleSubmit = React.useCallback(
27841
+ (value) => {
27842
+ if (submittedRef.current) return;
27843
+ const trimmed = value.trim();
27844
+ if (trimmed) {
27845
+ submittedRef.current = true;
27846
+ onSubmit(trimmed);
27847
+ } else {
27848
+ onCancel?.();
27849
+ }
27850
+ },
27851
+ [onSubmit, onCancel]
27852
+ );
27853
+ const handleKeyDown = React.useCallback(
27854
+ (e) => {
27855
+ if (e.key === "Enter") {
27856
+ e.preventDefault();
27857
+ handleSubmit(e.currentTarget.value);
27858
+ } else if (e.key === "Escape") {
27859
+ e.preventDefault();
27860
+ onCancel?.();
27861
+ }
27862
+ },
27863
+ [handleSubmit, onCancel]
27864
+ );
27865
+ const handleBlur = React.useCallback(
27866
+ (e) => {
27867
+ handleSubmit(e.currentTarget.value);
27868
+ },
27869
+ [handleSubmit]
27870
+ );
27871
+ const handleFocus = React.useCallback((e) => {
27872
+ e.currentTarget.select();
27873
+ }, []);
27874
+ const Icon = type === "folder" ? Folder : File$1;
27875
+ return /* @__PURE__ */ jsxs(
27876
+ "li",
27877
+ {
27878
+ ref,
27879
+ role: "treeitem",
27880
+ className: cn(
27881
+ "group flex h-7 min-w-0 items-center gap-1.5 rounded-sm px-1",
27882
+ transitions.colors,
27883
+ "focus-within:outline-none focus-within:ring-1 focus-within:ring-accent1 focus-within:shadow-focus-ring",
27884
+ className
27885
+ ),
27886
+ style: { paddingLeft: depth * 12 + 18 },
27887
+ children: [
27888
+ /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center [&>svg]:size-3.5", children: /* @__PURE__ */ jsx(Icon, { className: "text-neutral3" }) }),
27889
+ /* @__PURE__ */ jsx(
27890
+ "input",
27891
+ {
27892
+ ref: inputRef,
27893
+ type: "text",
27894
+ defaultValue,
27895
+ placeholder,
27896
+ autoFocus,
27897
+ onKeyDown: handleKeyDown,
27898
+ onBlur: handleBlur,
27899
+ onFocus: handleFocus,
27900
+ className: "min-w-0 flex-1 border-none bg-transparent text-xs text-neutral5 outline-none placeholder:text-neutral3"
27901
+ }
27902
+ )
27903
+ ]
27904
+ }
27905
+ );
27906
+ }
27907
+ );
27908
+ TreeInput.displayName = "Tree.Input";
27909
+
27910
+ const Tree = Object.assign(TreeRoot, {
27911
+ Folder: TreeFolder,
27912
+ FolderTrigger: TreeFolderTrigger,
27913
+ FolderContent: TreeFolderContent,
27914
+ File: TreeFile,
27915
+ Icon: TreeIcon,
27916
+ Label: TreeLabel,
27917
+ Input: TreeInput
27918
+ });
27919
+
27920
+ const STRUCTURAL_IDS = /* @__PURE__ */ new Set(["root", "skill-md", "license-md", "references", "scripts", "assets"]);
27921
+ function slugify(name) {
27922
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
27923
+ }
27924
+ function createInitialStructure(name) {
27925
+ const slug = slugify(name) || "untitled";
27926
+ return [
27927
+ {
27928
+ id: "root",
27929
+ name: slug,
27930
+ type: "folder",
27931
+ children: [
27932
+ { id: "skill-md", name: "SKILL.md", type: "file", content: "" },
27933
+ { id: "license-md", name: "LICENSE.md", type: "file", content: "" },
27934
+ { id: "references", name: "references", type: "folder", children: [] },
27935
+ { id: "scripts", name: "scripts", type: "folder", children: [] },
27936
+ { id: "assets", name: "assets", type: "folder", children: [] }
27937
+ ]
27938
+ }
27939
+ ];
27940
+ }
27941
+ function updateRootFolderName(files, name) {
27942
+ const slug = slugify(name) || "untitled";
27943
+ return files.map((node) => node.id === "root" ? { ...node, name: slug } : node);
27944
+ }
27945
+ function extractSkillInstructions(files) {
27946
+ const root = files.find((n) => n.id === "root");
27947
+ if (!root?.children) return "";
27948
+ const skillMd = root.children.find((n) => n.id === "skill-md");
27949
+ return skillMd?.content ?? "";
27950
+ }
27951
+ function extractSkillLicense(files) {
27952
+ const root = files.find((n) => n.id === "root");
27953
+ if (!root?.children) return void 0;
27954
+ const licenseMd = root.children.find((n) => n.id === "license-md");
27955
+ const content = licenseMd?.content?.trim();
27956
+ return content || void 0;
27957
+ }
27958
+ function isImageContent(content) {
27959
+ return !!content && content.startsWith("data:image/");
27960
+ }
27961
+ function getFileIcon$1(name) {
27962
+ const ext = name.split(".").pop()?.toLowerCase();
27963
+ switch (ext) {
27964
+ case "ts":
27965
+ case "tsx":
27966
+ case "js":
27967
+ case "jsx":
27968
+ return /* @__PURE__ */ jsx(FileCode, { className: "text-blue-400" });
27969
+ case "json":
27970
+ return /* @__PURE__ */ jsx(FileJson, { className: "text-yellow-400" });
27971
+ case "md":
27972
+ case "mdx":
27973
+ return /* @__PURE__ */ jsx(FileText, { className: "text-neutral4" });
27974
+ case "png":
27975
+ case "jpg":
27976
+ case "jpeg":
27977
+ case "gif":
27978
+ case "svg":
27979
+ case "webp":
27980
+ return /* @__PURE__ */ jsx(Image, { className: "text-purple-400" });
27981
+ default:
27982
+ return /* @__PURE__ */ jsx(File$1, { className: "text-neutral4" });
27983
+ }
27984
+ }
27985
+ function getFolderIcon(isOpen) {
27986
+ return isOpen ? /* @__PURE__ */ jsx(FolderOpen, { className: "text-amber-400" }) : /* @__PURE__ */ jsx(Folder, { className: "text-amber-400" });
27987
+ }
27988
+ function insertNode(nodes, parentId, newNode) {
27989
+ return nodes.map((node) => {
27990
+ if (node.id === parentId && node.type === "folder") {
27991
+ return { ...node, children: [...node.children ?? [], newNode] };
27992
+ }
27993
+ if (node.children) {
27994
+ return { ...node, children: insertNode(node.children, parentId, newNode) };
27995
+ }
27996
+ return node;
27997
+ });
27998
+ }
27999
+ function removeNode(nodes, nodeId) {
28000
+ return nodes.filter((node) => node.id !== nodeId).map((node) => {
28001
+ if (node.children) {
28002
+ return { ...node, children: removeNode(node.children, nodeId) };
28003
+ }
28004
+ return node;
28005
+ });
28006
+ }
28007
+ function updateNodeContent(nodes, nodeId, content) {
28008
+ return nodes.map((node) => {
28009
+ if (node.id === nodeId) {
28010
+ return { ...node, content };
28011
+ }
28012
+ if (node.children) {
28013
+ return { ...node, children: updateNodeContent(node.children, nodeId, content) };
28014
+ }
28015
+ return node;
28016
+ });
28017
+ }
28018
+ function FolderAddAction({ tooltip, onClick }) {
28019
+ return /* @__PURE__ */ jsx("span", { className: "opacity-0 group-hover:opacity-100", children: /* @__PURE__ */ jsx(IconButton, { size: "sm", variant: "ghost", tooltip, onClick, children: /* @__PURE__ */ jsx(Plus, {}) }) });
28020
+ }
28021
+ function FileDeleteAction({ nodeId, onRemove }) {
28022
+ return /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 opacity-0 group-hover:opacity-100", children: /* @__PURE__ */ jsx(
28023
+ IconButton,
28024
+ {
28025
+ size: "sm",
28026
+ variant: "ghost",
28027
+ tooltip: "Delete file",
28028
+ onClick: (e) => {
28029
+ e.stopPropagation();
28030
+ onRemove(nodeId);
28031
+ },
28032
+ children: /* @__PURE__ */ jsx(Trash2, {})
28033
+ }
28034
+ ) });
28035
+ }
28036
+ function UserFileList({
28037
+ nodes,
28038
+ readOnly,
28039
+ onRemove
28040
+ }) {
28041
+ return nodes.filter((n) => !STRUCTURAL_IDS.has(n.id)).map((node) => /* @__PURE__ */ jsxs(Tree.File, { id: node.id, children: [
28042
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFileIcon$1(node.name) }),
28043
+ /* @__PURE__ */ jsx(Tree.Label, { children: node.name }),
28044
+ !readOnly && !STRUCTURAL_IDS.has(node.id) && /* @__PURE__ */ jsx(FileDeleteAction, { nodeId: node.id, onRemove })
28045
+ ] }, node.id));
28046
+ }
28047
+ function SkillFileTree({ files, onChange, selectedFileId, onSelectFile, readOnly }) {
28048
+ const [pendingInput, setPendingInput] = useState(null);
28049
+ const [openFolders, setOpenFolders] = useState({
28050
+ references: true,
28051
+ scripts: true,
28052
+ assets: true
28053
+ });
28054
+ const imageInputRef = useRef(null);
28055
+ const setFolderOpen = useCallback((folderId, open) => {
28056
+ setOpenFolders((prev) => ({ ...prev, [folderId]: open }));
28057
+ }, []);
28058
+ const handleAddFile = useCallback(
28059
+ (parentId) => {
28060
+ setFolderOpen(parentId, true);
28061
+ setPendingInput({ parentId, type: "file" });
28062
+ },
28063
+ [setFolderOpen]
28064
+ );
28065
+ const handleAddImage = useCallback(() => {
28066
+ setFolderOpen("assets", true);
28067
+ imageInputRef.current?.click();
28068
+ }, [setFolderOpen]);
28069
+ const handleImagePicked = useCallback(
28070
+ (e) => {
28071
+ const file = e.target.files?.[0];
28072
+ if (!file) return;
28073
+ const reader = new FileReader();
28074
+ reader.onload = () => {
28075
+ const base64 = reader.result;
28076
+ const newNode = {
28077
+ id: v4(),
28078
+ name: file.name,
28079
+ type: "file",
28080
+ content: base64
28081
+ };
28082
+ onChange(insertNode(files, "assets", newNode));
28083
+ onSelectFile(newNode.id);
28084
+ };
28085
+ reader.readAsDataURL(file);
28086
+ e.target.value = "";
28087
+ },
28088
+ [files, onChange, onSelectFile]
28089
+ );
28090
+ const handleInputSubmit = useCallback(
28091
+ (name) => {
28092
+ if (!pendingInput) return;
28093
+ const newNode = {
28094
+ id: v4(),
28095
+ name,
28096
+ type: "file",
28097
+ content: ""
28098
+ };
28099
+ onChange(insertNode(files, pendingInput.parentId, newNode));
28100
+ setPendingInput(null);
28101
+ },
28102
+ [pendingInput, files, onChange]
28103
+ );
28104
+ const handleInputCancel = useCallback(() => {
28105
+ setPendingInput(null);
28106
+ }, []);
28107
+ const handleRemove = useCallback(
28108
+ (nodeId) => {
28109
+ if (STRUCTURAL_IDS.has(nodeId)) return;
28110
+ if (selectedFileId === nodeId) {
28111
+ onSelectFile(null);
28112
+ }
28113
+ onChange(removeNode(files, nodeId));
28114
+ },
28115
+ [files, onChange, selectedFileId, onSelectFile]
28116
+ );
28117
+ const root = files.find((n) => n.id === "root");
28118
+ if (!root?.children) return null;
28119
+ const referencesFolder = root.children.find((n) => n.id === "references");
28120
+ const scriptsFolder = root.children.find((n) => n.id === "scripts");
28121
+ const assetsFolder = root.children.find((n) => n.id === "assets");
28122
+ return /* @__PURE__ */ jsxs(TooltipProvider, { children: [
28123
+ /* @__PURE__ */ jsx("input", { ref: imageInputRef, type: "file", accept: "image/*", className: "hidden", onChange: handleImagePicked }),
28124
+ /* @__PURE__ */ jsx(Tree, { selectedId: selectedFileId ?? void 0, onSelect: onSelectFile, children: /* @__PURE__ */ jsxs(Tree.Folder, { defaultOpen: true, children: [
28125
+ /* @__PURE__ */ jsxs(Tree.FolderTrigger, { children: [
28126
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFolderIcon(true) }),
28127
+ /* @__PURE__ */ jsx(Tree.Label, { children: root.name })
28128
+ ] }),
28129
+ /* @__PURE__ */ jsxs(Tree.FolderContent, { children: [
28130
+ /* @__PURE__ */ jsxs(Tree.File, { id: "skill-md", children: [
28131
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFileIcon$1("SKILL.md") }),
28132
+ /* @__PURE__ */ jsx(Tree.Label, { children: "SKILL.md" })
28133
+ ] }),
28134
+ /* @__PURE__ */ jsxs(Tree.File, { id: "license-md", children: [
28135
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFileIcon$1("LICENSE.md") }),
28136
+ /* @__PURE__ */ jsx(Tree.Label, { children: "LICENSE.md" })
28137
+ ] }),
28138
+ referencesFolder && /* @__PURE__ */ jsxs(Tree.Folder, { open: openFolders.references, onOpenChange: (open) => setFolderOpen("references", open), children: [
28139
+ /* @__PURE__ */ jsxs(
28140
+ Tree.FolderTrigger,
28141
+ {
28142
+ actions: !readOnly && /* @__PURE__ */ jsx(FolderAddAction, { tooltip: "New file", onClick: () => handleAddFile("references") }),
28143
+ children: [
28144
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFolderIcon(openFolders.references) }),
28145
+ /* @__PURE__ */ jsx(Tree.Label, { children: "references" })
28146
+ ]
28147
+ }
28148
+ ),
28149
+ /* @__PURE__ */ jsxs(Tree.FolderContent, { children: [
28150
+ /* @__PURE__ */ jsx(UserFileList, { nodes: referencesFolder.children ?? [], readOnly, onRemove: handleRemove }),
28151
+ pendingInput?.parentId === "references" && /* @__PURE__ */ jsx(Tree.Input, { type: "file", onSubmit: handleInputSubmit, onCancel: handleInputCancel })
28152
+ ] })
28153
+ ] }),
28154
+ scriptsFolder && /* @__PURE__ */ jsxs(Tree.Folder, { open: openFolders.scripts, onOpenChange: (open) => setFolderOpen("scripts", open), children: [
28155
+ /* @__PURE__ */ jsxs(
28156
+ Tree.FolderTrigger,
28157
+ {
28158
+ actions: !readOnly && /* @__PURE__ */ jsx(FolderAddAction, { tooltip: "New file", onClick: () => handleAddFile("scripts") }),
28159
+ children: [
28160
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFolderIcon(openFolders.scripts) }),
28161
+ /* @__PURE__ */ jsx(Tree.Label, { children: "scripts" })
28162
+ ]
28163
+ }
28164
+ ),
28165
+ /* @__PURE__ */ jsxs(Tree.FolderContent, { children: [
28166
+ /* @__PURE__ */ jsx(UserFileList, { nodes: scriptsFolder.children ?? [], readOnly, onRemove: handleRemove }),
28167
+ pendingInput?.parentId === "scripts" && /* @__PURE__ */ jsx(Tree.Input, { type: "file", onSubmit: handleInputSubmit, onCancel: handleInputCancel })
28168
+ ] })
28169
+ ] }),
28170
+ assetsFolder && /* @__PURE__ */ jsxs(Tree.Folder, { open: openFolders.assets, onOpenChange: (open) => setFolderOpen("assets", open), children: [
28171
+ /* @__PURE__ */ jsxs(
28172
+ Tree.FolderTrigger,
28173
+ {
28174
+ actions: !readOnly && /* @__PURE__ */ jsx(FolderAddAction, { tooltip: "Add image", onClick: handleAddImage }),
28175
+ children: [
28176
+ /* @__PURE__ */ jsx(Tree.Icon, { children: getFolderIcon(openFolders.assets) }),
28177
+ /* @__PURE__ */ jsx(Tree.Label, { children: "assets" })
28178
+ ]
28179
+ }
28180
+ ),
28181
+ /* @__PURE__ */ jsx(Tree.FolderContent, { children: /* @__PURE__ */ jsx(UserFileList, { nodes: assetsFolder.children ?? [], readOnly, onRemove: handleRemove }) })
28182
+ ] })
28183
+ ] })
28184
+ ] }) })
28185
+ ] });
28186
+ }
28187
+
28188
+ function flattenFiles(nodes, basePath) {
28189
+ const results = [];
28190
+ for (const node of nodes) {
28191
+ const nodePath = basePath ? `${basePath}/${node.name}` : node.name;
28192
+ if (node.type === "file" && node.content !== void 0) {
28193
+ results.push({ path: nodePath, content: node.content });
28194
+ } else if (node.type === "folder" && node.children) {
28195
+ results.push(...flattenFiles(node.children, nodePath));
28196
+ }
28197
+ }
28198
+ return results;
28199
+ }
28200
+ function useCreateSkill() {
28201
+ const client = useMastraClient();
28202
+ const queryClient = useQueryClient();
28203
+ const writeFile = useWriteWorkspaceFile();
28204
+ return useMutation({
28205
+ mutationFn: async (params) => {
28206
+ const { name, description, workspaceId, files } = params;
28207
+ const filesToWrite = flattenFiles(files, "");
28208
+ await Promise.all(
28209
+ filesToWrite.map(
28210
+ (file) => writeFile.mutateAsync({
28211
+ workspaceId,
28212
+ path: `skills/${file.path}`,
28213
+ content: file.content,
28214
+ recursive: true
28215
+ })
28216
+ )
28217
+ );
28218
+ return client.createStoredSkill({
28219
+ name,
28220
+ description,
28221
+ instructions: extractSkillInstructions(files),
28222
+ license: extractSkillLicense(files),
28223
+ files
28224
+ });
28225
+ },
28226
+ onSuccess: (_, variables) => {
28227
+ queryClient.invalidateQueries({ queryKey: ["stored-skills"] });
28228
+ queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
28229
+ toast.success("Skill created");
28230
+ },
28231
+ onError: (error) => {
28232
+ toast.error(`Failed to create skill: ${error instanceof Error ? error.message : "Unknown error"}`);
28233
+ }
28234
+ });
28235
+ }
28236
+
28237
+ function findFileContent(nodes, fileId) {
28238
+ for (const node of nodes) {
28239
+ if (node.id === fileId && node.type === "file") return node.content ?? "";
28240
+ if (node.children) {
28241
+ const found = findFileContent(node.children, fileId);
28242
+ if (found !== void 0) return found;
28243
+ }
28244
+ }
28245
+ return void 0;
28246
+ }
28247
+ function findFileName(nodes, fileId) {
28248
+ for (const node of nodes) {
28249
+ if (node.id === fileId) return node.name;
28250
+ if (node.children) {
28251
+ const found = findFileName(node.children, fileId);
28252
+ if (found !== void 0) return found;
28253
+ }
28254
+ }
28255
+ return void 0;
28256
+ }
28257
+ function SkillFolder({
28258
+ files,
28259
+ onChange,
28260
+ readOnly,
28261
+ workspaceId,
28262
+ setWorkspaceId,
28263
+ workspaceOptions
28264
+ }) {
28265
+ const [selectedFileId, setSelectedFileId] = useState(null);
28266
+ const handleFileContentChange = useCallback(
28267
+ (content) => {
28268
+ if (!selectedFileId) return;
28269
+ onChange(updateNodeContent(files, selectedFileId, content));
28270
+ },
28271
+ [selectedFileId, files, onChange]
28272
+ );
28273
+ const selectedFileContent = useMemo(() => {
28274
+ if (!selectedFileId) return void 0;
28275
+ return findFileContent(files, selectedFileId);
28276
+ }, [files, selectedFileId]);
28277
+ const selectedFileName = useMemo(() => {
28278
+ if (!selectedFileId) return void 0;
28279
+ return findFileName(files, selectedFileId);
28280
+ }, [files, selectedFileId]);
28281
+ const editorLanguage = useMemo(() => {
28282
+ if (!selectedFileName) return void 0;
28283
+ if (selectedFileName.endsWith(".md")) return "markdown";
28284
+ if (selectedFileName.endsWith(".json")) return "json";
28285
+ return void 0;
28286
+ }, [selectedFileName]);
28287
+ const isFileSelected = selectedFileId !== null && selectedFileContent !== void 0;
28288
+ const isImage = isImageContent(selectedFileContent);
28289
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[300px_1fr] h-full", children: [
28290
+ /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto h-full border-r border-border1 p-4", children: [
28291
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 pb-4", children: [
28292
+ /* @__PURE__ */ jsx(Txt, { as: "label", variant: "ui-sm", className: "text-neutral3", children: "Workspace" }),
28293
+ /* @__PURE__ */ jsx(
28294
+ Combobox,
28295
+ {
28296
+ options: workspaceOptions,
28297
+ value: workspaceId,
28298
+ onValueChange: setWorkspaceId,
28299
+ placeholder: "Select a workspace...",
28300
+ disabled: readOnly,
28301
+ variant: "default"
28302
+ }
28303
+ )
28304
+ ] }),
28305
+ /* @__PURE__ */ jsx(
28306
+ SkillFileTree,
28307
+ {
28308
+ files,
28309
+ onChange,
28310
+ selectedFileId,
28311
+ onSelectFile: setSelectedFileId,
28312
+ readOnly
28313
+ }
28314
+ )
28315
+ ] }),
28316
+ /* @__PURE__ */ jsx("div", { className: "h-full p-4", children: isFileSelected ? /* @__PURE__ */ jsx(Fragment, { children: isImage ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 p-4 bg-surface2", children: /* @__PURE__ */ jsx(
28317
+ "img",
28318
+ {
28319
+ src: selectedFileContent,
28320
+ alt: selectedFileName,
28321
+ className: "max-w-full max-h-[300px] rounded-md object-contain"
28322
+ }
28323
+ ) }) : /* @__PURE__ */ jsx(
28324
+ CodeEditor,
28325
+ {
28326
+ language: editorLanguage,
28327
+ value: selectedFileContent,
28328
+ onChange: readOnly ? void 0 : (val) => handleFileContentChange(val ?? ""),
28329
+ showCopyButton: false,
28330
+ autoFocus: true,
28331
+ className: "h-full"
28332
+ },
28333
+ selectedFileId
28334
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full text-xs text-neutral3", children: "Select a file to edit its content" }) })
28335
+ ] });
28336
+ }
28337
+
28338
+ function SkillEditDialog({ isOpen, onClose, onSkillCreated, readOnly }) {
28339
+ const [name, setName] = useState("");
28340
+ const [description, setDescription] = useState("");
28341
+ const [workspaceId, setWorkspaceId] = useState("");
28342
+ const [files, setFiles] = useState([]);
28343
+ const prevNameRef = useRef("");
28344
+ const createSkill = useCreateSkill();
28345
+ const { data: workspacesData } = useWorkspaces();
28346
+ const workspaceOptions = useMemo(
28347
+ () => (workspacesData?.workspaces ?? []).map((ws) => ({ value: ws.id, label: ws.name })),
28348
+ [workspacesData]
28349
+ );
28350
+ useEffect(() => {
28351
+ if (isOpen) {
28352
+ setName("");
28353
+ setDescription("");
28354
+ setWorkspaceId(workspaceOptions.length === 1 ? workspaceOptions[0].value : "");
28355
+ setFiles([]);
28356
+ prevNameRef.current = "";
28357
+ }
28358
+ }, [isOpen, workspaceOptions]);
28359
+ const handleNameChange = useCallback(
28360
+ (newName) => {
28361
+ setName(newName);
28362
+ const hasStructure = files.some((n) => n.id === "root");
28363
+ if (!hasStructure && newName.trim()) {
28364
+ setFiles(createInitialStructure(newName));
28365
+ } else if (hasStructure) {
28366
+ setFiles((prev) => updateRootFolderName(prev, newName));
28367
+ }
28368
+ prevNameRef.current = newName;
28369
+ },
28370
+ [files]
28371
+ );
28372
+ const handleSave = useCallback(async () => {
28373
+ const result = await createSkill.mutateAsync({
28374
+ name,
28375
+ description,
28376
+ workspaceId,
28377
+ files
28378
+ });
28379
+ onSkillCreated(result, workspaceId);
28380
+ onClose();
28381
+ }, [name, description, workspaceId, files, createSkill, onSkillCreated, onClose]);
28382
+ return /* @__PURE__ */ jsxs(
28383
+ SideDialog,
28384
+ {
28385
+ dialogTitle: "Add Skill",
28386
+ dialogDescription: "Configure skill details and workspace files",
28387
+ isOpen,
28388
+ onClose,
28389
+ className: "h-full",
28390
+ children: [
28391
+ /* @__PURE__ */ jsxs(SideDialog.Top, { children: [
28392
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: "New Skill" }),
28393
+ !readOnly && /* @__PURE__ */ jsx(
28394
+ Button,
28395
+ {
28396
+ variant: "primary",
28397
+ size: "sm",
28398
+ onClick: handleSave,
28399
+ disabled: !name.trim() || !workspaceId || createSkill.isPending,
28400
+ className: "mr-6",
28401
+ children: createSkill.isPending ? "Creating..." : "Save"
28402
+ }
28403
+ )
28404
+ ] }),
28405
+ /* @__PURE__ */ jsxs(SideDialog.Content, { className: "overflow-y-auto h-full grid-rows-[auto_1fr]", children: [
28406
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
28407
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
28408
+ /* @__PURE__ */ jsx(Txt, { as: "label", variant: "ui-sm", className: "text-neutral3", children: "Name" }),
28409
+ /* @__PURE__ */ jsx(
28410
+ Input,
28411
+ {
28412
+ value: name,
28413
+ onChange: (e) => handleNameChange(e.target.value),
28414
+ placeholder: "Skill name",
28415
+ disabled: readOnly
28416
+ }
28417
+ )
28418
+ ] }),
28419
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
28420
+ /* @__PURE__ */ jsx(Txt, { as: "label", variant: "ui-sm", className: "text-neutral3", children: "Description" }),
28421
+ /* @__PURE__ */ jsx(
28422
+ Input,
28423
+ {
28424
+ value: description,
28425
+ onChange: (e) => setDescription(e.target.value),
28426
+ placeholder: "Brief description of the skill",
28427
+ disabled: readOnly
28428
+ }
28429
+ )
28430
+ ] })
28431
+ ] }),
28432
+ /* @__PURE__ */ jsx("div", { className: "h-full border border-border1 rounded-lg overflow-hidden", children: /* @__PURE__ */ jsx(
28433
+ SkillFolder,
28434
+ {
28435
+ files,
28436
+ onChange: setFiles,
28437
+ readOnly,
28438
+ workspaceOptions,
28439
+ workspaceId,
28440
+ setWorkspaceId
28441
+ }
28442
+ ) })
28443
+ ] })
28444
+ ]
28445
+ }
28446
+ );
28447
+ }
28448
+
28449
+ function SkillsPage() {
28450
+ const { form, readOnly } = useAgentEditFormContext();
28451
+ const { control } = form;
28452
+ const { data: storedSkillsResponse, isLoading } = useStoredSkills();
28453
+ const [dialogOpen, setDialogOpen] = useState(false);
28454
+ const [search, setSearch] = useState("");
28455
+ const selectedSkills = useWatch({ control, name: "skills" }) ?? {};
28456
+ const selectedSkillIds = Object.keys(selectedSkills);
28457
+ const storedSkills = storedSkillsResponse?.skills ?? [];
28458
+ const getSkillDescription = (skillId) => {
28459
+ const skill = storedSkills.find((s) => s.id === skillId);
28460
+ return skill?.description || "";
28461
+ };
28462
+ const handleToggleSkill = (skillId) => {
28463
+ const currentSkills = form.getValues("skills") ?? {};
28464
+ const isSelected = currentSkills[skillId] !== void 0;
28465
+ if (isSelected) {
28466
+ const next = { ...currentSkills };
28467
+ delete next[skillId];
28468
+ form.setValue("skills", next);
28469
+ } else {
28470
+ form.setValue("skills", {
28471
+ ...currentSkills,
28472
+ [skillId]: { description: getSkillDescription(skillId) }
28473
+ });
28474
+ }
28475
+ };
28476
+ const handleSkillCreated = (skill, workspaceId) => {
28477
+ const currentSkills = form.getValues("skills") ?? {};
28478
+ form.setValue("skills", {
28479
+ ...currentSkills,
28480
+ [skill.id]: { description: skill.description || "" }
28481
+ });
28482
+ form.setValue("workspace", { type: "id", workspaceId });
28483
+ setDialogOpen(false);
28484
+ };
28485
+ const filteredSkills = storedSkills.filter((skill) => skill.name.toLowerCase().includes(search.toLowerCase()));
28486
+ const totalCount = selectedSkillIds.length;
28487
+ return /* @__PURE__ */ jsxs(ScrollArea, { className: "h-full", children: [
28488
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
28489
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
28490
+ /* @__PURE__ */ jsx(
28491
+ SectionHeader$1,
28492
+ {
28493
+ title: "Skills",
28494
+ subtitle: `Give your agent specialized knowledge by using skills.${totalCount > 0 ? ` (${totalCount} selected)` : ""}`
28495
+ }
28496
+ ),
28497
+ !readOnly && /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => setDialogOpen(true), children: [
28498
+ /* @__PURE__ */ jsx(Plus, { className: "size-3" }),
28499
+ "Add a skill"
28500
+ ] })
28501
+ ] }),
28502
+ /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search skills", placeholder: "Search skills" }),
28503
+ filteredSkills.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: filteredSkills.map((skill) => /* @__PURE__ */ jsxs(Entity, { className: "bg-surface2", children: [
28504
+ /* @__PURE__ */ jsxs(EntityContent, { children: [
28505
+ /* @__PURE__ */ jsx(EntityName, { children: skill.name }),
28506
+ /* @__PURE__ */ jsx(EntityDescription, { children: skill.description || "No description" })
28507
+ ] }),
28508
+ !readOnly && /* @__PURE__ */ jsx(
28509
+ Switch,
28510
+ {
28511
+ checked: selectedSkillIds.includes(skill.id),
28512
+ onCheckedChange: () => handleToggleSkill(skill.id)
28513
+ }
28514
+ )
28515
+ ] }, skill.id)) }),
28516
+ !isLoading && storedSkills.length === 0 && /* @__PURE__ */ jsx("div", { className: "py-12", children: /* @__PURE__ */ jsx(
28517
+ EmptyState$1,
28518
+ {
28519
+ iconSlot: /* @__PURE__ */ jsx(Drill, { height: 40, width: 40 }),
28520
+ titleSlot: "No skills available",
28521
+ descriptionSlot: "Create a skill to give your agent specialized knowledge.",
28522
+ actionSlot: !readOnly ? /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => setDialogOpen(true), children: [
28523
+ /* @__PURE__ */ jsx(Plus, { className: "size-3" }),
28524
+ "Add a skill"
28525
+ ] }) : void 0
28526
+ }
28527
+ ) })
28528
+ ] }),
28529
+ /* @__PURE__ */ jsx(
28530
+ SkillEditDialog,
28531
+ {
28532
+ isOpen: dialogOpen,
28533
+ onClose: () => setDialogOpen(false),
28534
+ onSkillCreated: handleSkillCreated,
28535
+ readOnly
28536
+ }
28537
+ )
28538
+ ] });
28539
+ }
28540
+
28541
+ const arrayToRecord = (arr) => {
28542
+ const record = {};
28543
+ for (const id of arr) {
28544
+ record[id] = { description: void 0 };
28545
+ }
28546
+ return record;
28547
+ };
28548
+ const normalizeToolsToRecord = (tools) => {
28549
+ if (!tools) return {};
28550
+ if (!Array.isArray(tools)) return { ...tools };
28551
+ const result = {};
28552
+ for (const item of tools) {
28553
+ if (typeof item === "string") {
28554
+ result[item] = { description: void 0 };
28555
+ } else {
28556
+ Object.assign(result, item.value);
28557
+ }
28558
+ }
28559
+ return result;
28560
+ };
28561
+ const splitModelId = (id) => {
28562
+ if (!id) return void 0;
28563
+ const [p, ...rest] = id.split("/");
28564
+ const n = rest.join("/");
28565
+ return p && n ? { provider: p, name: n } : void 0;
28566
+ };
28567
+ const joinModelId = (m) => m?.provider && m?.name ? `${m.provider}/${m.name}` : void 0;
28568
+ const transformIntegrationToolsForApi = (integrationTools) => {
28569
+ if (!integrationTools || Object.keys(integrationTools).length === 0) return void 0;
28570
+ const result = {};
28571
+ for (const [compositeKey, config] of Object.entries(integrationTools)) {
28572
+ const separatorIndex = compositeKey.indexOf(":");
28573
+ if (separatorIndex === -1) continue;
28574
+ const providerId = compositeKey.slice(0, separatorIndex);
28575
+ const toolSlug = compositeKey.slice(separatorIndex + 1);
28576
+ if (!result[providerId]) {
28577
+ result[providerId] = { tools: {} };
28578
+ }
28579
+ result[providerId].tools[toolSlug] = { description: config.description, rules: config.rules };
28580
+ }
28581
+ return result;
28582
+ };
28583
+ const normalizeIntegrationToolsToRecord = (integrationTools) => {
28584
+ if (!integrationTools) return {};
28585
+ const result = {};
28586
+ for (const [providerId, providerConfig] of Object.entries(integrationTools)) {
28587
+ if (providerConfig.tools) {
28588
+ for (const [toolSlug, toolConfig] of Object.entries(providerConfig.tools)) {
28589
+ result[`${providerId}:${toolSlug}`] = { description: toolConfig.description, rules: toolConfig.rules };
28590
+ }
28591
+ }
28592
+ }
28593
+ return result;
28594
+ };
28595
+ const normalizeSkillsFromApi = (skills) => {
28596
+ if (!skills) return {};
28597
+ if (Array.isArray(skills)) {
28598
+ const result2 = {};
28599
+ for (const variant of skills) {
28600
+ for (const [key, value] of Object.entries(variant.value)) {
28601
+ result2[key] = {
28602
+ description: value.description,
28603
+ instructions: value.instructions,
28604
+ pin: value.pin,
28605
+ strategy: value.strategy
28606
+ };
28607
+ }
28608
+ }
28609
+ return result2;
28610
+ }
28611
+ const result = {};
28612
+ for (const [key, value] of Object.entries(skills)) {
28613
+ result[key] = {
28614
+ description: value.description,
28615
+ instructions: value.instructions,
28616
+ pin: value.pin,
28617
+ strategy: value.strategy
28618
+ };
28619
+ }
28620
+ return result;
28621
+ };
28622
+ const normalizeWorkspaceFromApi = (workspace) => {
28623
+ if (!workspace) return void 0;
28624
+ if (Array.isArray(workspace)) {
28625
+ return workspace[0]?.value;
28626
+ }
28627
+ return workspace;
28628
+ };
28629
+ const mapInstructionBlocksToApi = (blocks) => (blocks ?? []).map((block) => ({
28630
+ type: block.type,
28631
+ content: block.content,
28632
+ rules: block.rules
28633
+ }));
28634
+ const mapInstructionBlocksFromApi = (instructionsRaw) => {
28635
+ const instructionsString = Array.isArray(instructionsRaw) ? instructionsRaw.map((b) => b.type === "prompt_block" ? b.content : "").filter(Boolean).join("\n\n") : instructionsRaw || "";
28636
+ const instructionBlocks = Array.isArray(instructionsRaw) ? instructionsRaw.filter(
28637
+ (b) => b.type === "prompt_block"
28638
+ ).map((b) => createInstructionBlock(b.content, b.rules)) : [createInstructionBlock(instructionsRaw || "")];
28639
+ return { instructionsString, instructionBlocks };
28640
+ };
28641
+ const mapScorersToApi = (scorers) => {
28642
+ const entries = scorers ? Object.entries(scorers) : void 0;
28643
+ if (!entries) return void 0;
28644
+ return Object.fromEntries(
28645
+ entries.map(([key, value]) => [
28646
+ key,
28647
+ {
28648
+ description: value.description,
28649
+ sampling: value.sampling ? {
28650
+ type: value.sampling.type,
28651
+ rate: value.sampling.rate || 0
28652
+ } : void 0,
28653
+ rules: value.rules
28654
+ }
28655
+ ])
28656
+ );
28657
+ };
28658
+ const normalizeScorersFromApi = (scorers) => {
28659
+ if (!scorers) return {};
28660
+ let record;
28661
+ if (Array.isArray(scorers)) {
28662
+ record = {};
28663
+ for (const variant of scorers) {
28664
+ Object.assign(record, variant.value);
28665
+ }
28666
+ } else {
28667
+ record = scorers;
28668
+ }
28669
+ const result = {};
28670
+ for (const [key, value] of Object.entries(record)) {
28671
+ result[key] = {
28672
+ description: value.description,
28673
+ sampling: value.sampling?.type === "ratio" ? { type: "ratio", rate: value.sampling.rate } : void 0,
28674
+ rules: value.rules
28675
+ };
28676
+ }
28677
+ return result;
28678
+ };
28679
+ const buildObservationalMemoryForApi = (om) => {
28680
+ if (!om?.enabled) return void 0;
28681
+ const modelId = joinModelId(om.model);
28682
+ const obsModelId = joinModelId(om.observation?.model);
28683
+ const observation = obsModelId || om.observation?.messageTokens || om.observation?.maxTokensPerBatch || om.observation?.bufferTokens !== void 0 || om.observation?.bufferActivation !== void 0 || om.observation?.blockAfter !== void 0 ? {
28684
+ model: obsModelId,
28685
+ messageTokens: om.observation?.messageTokens,
28686
+ maxTokensPerBatch: om.observation?.maxTokensPerBatch,
26924
28687
  bufferTokens: om.observation?.bufferTokens,
26925
28688
  bufferActivation: om.observation?.bufferActivation,
26926
28689
  blockAfter: om.observation?.blockAfter
@@ -27006,6 +28769,8 @@ function computeAgentInitialValues(dataSource) {
27006
28769
  observationalMemory: parseObservationalMemoryFromApi(memoryData.observationalMemory)
27007
28770
  } : void 0,
27008
28771
  instructionBlocks,
28772
+ skills: normalizeSkillsFromApi(dataSource.skills),
28773
+ workspace: normalizeWorkspaceFromApi(dataSource.workspace),
27009
28774
  variables: dataSource.requestContextSchema
27010
28775
  };
27011
28776
  }
@@ -27031,15 +28796,22 @@ function useAgentCmsForm(options) {
27031
28796
  const ids = Object.keys(mcpClientRecord ?? {});
27032
28797
  if (ids.length === 0) return;
27033
28798
  Promise.all(ids.map((id) => client.getStoredMCPClient(id).details())).then((results) => {
27034
- form.setValue(
27035
- "mcpClients",
27036
- results.map((r) => ({
27037
- id: r.id,
27038
- name: r.name,
27039
- description: r.description,
27040
- servers: r.servers
27041
- }))
27042
- );
28799
+ const mcpClientValues = results.map((r) => ({
28800
+ id: r.id,
28801
+ name: r.name,
28802
+ description: r.description,
28803
+ servers: r.servers,
28804
+ selectedTools: mcpClientRecord?.[r.id]?.tools ?? {}
28805
+ }));
28806
+ form.setValue("mcpClients", mcpClientValues, { shouldDirty: true });
28807
+ const currentTools = form.getValues("tools") ?? {};
28808
+ const next = { ...currentTools };
28809
+ for (const mcpClient of mcpClientValues) {
28810
+ for (const [name, config] of Object.entries(mcpClient.selectedTools ?? {})) {
28811
+ next[name] = { description: config.description };
28812
+ }
28813
+ }
28814
+ form.setValue("tools", next, { shouldDirty: true });
27043
28815
  }).catch(() => {
27044
28816
  });
27045
28817
  });
@@ -27053,19 +28825,38 @@ function useAgentCmsForm(options) {
27053
28825
  const mcpClientsToDelete = values.mcpClientsToDelete ?? [];
27054
28826
  await Promise.all(mcpClientsToDelete.map((id) => client.getStoredMCPClient(id).delete()));
27055
28827
  }
28828
+ const mcpToolNames = /* @__PURE__ */ new Set();
28829
+ for (const c of values.mcpClients ?? []) {
28830
+ for (const name of Object.keys(c.selectedTools ?? {})) {
28831
+ mcpToolNames.add(name);
28832
+ }
28833
+ }
28834
+ const registryTools = {};
28835
+ for (const [name, config] of Object.entries(values.tools ?? {})) {
28836
+ if (!mcpToolNames.has(name)) {
28837
+ registryTools[name] = config;
28838
+ }
28839
+ }
27056
28840
  const mcpClientIds = await collectMCPClientIds(values.mcpClients ?? [], client);
27057
- const mcpClientsParam = Object.fromEntries(mcpClientIds.map((id) => [id, {}]));
28841
+ const mcpClientsParam = Object.fromEntries(
28842
+ mcpClientIds.map((id, index) => {
28843
+ const selectedTools = values.mcpClients?.[index]?.selectedTools ?? {};
28844
+ return [id, { tools: selectedTools }];
28845
+ })
28846
+ );
27058
28847
  return {
27059
28848
  name: values.name,
27060
28849
  description: values.description || void 0,
27061
28850
  instructions: mapInstructionBlocksToApi(values.instructionBlocks),
27062
28851
  model: values.model,
27063
- tools: values.tools && Object.keys(values.tools).length > 0 ? values.tools : void 0,
28852
+ tools: Object.keys(registryTools).length > 0 ? registryTools : void 0,
27064
28853
  integrationTools: transformIntegrationToolsForApi(values.integrationTools),
27065
28854
  workflows: values.workflows && Object.keys(values.workflows).length > 0 ? values.workflows : void 0,
27066
28855
  agents: values.agents && Object.keys(values.agents).length > 0 ? values.agents : void 0,
27067
28856
  mcpClients: mcpClientsParam,
27068
28857
  scorers: mapScorersToApi(values.scorers),
28858
+ skills: values.skills,
28859
+ workspace: values.workspace,
27069
28860
  requestContextSchema: values.variables ? Object.fromEntries(Object.entries(values.variables)) : void 0
27070
28861
  };
27071
28862
  },
@@ -27103,6 +28894,7 @@ function useAgentCmsForm(options) {
27103
28894
  ...sharedParams,
27104
28895
  memory: editMemory
27105
28896
  });
28897
+ form.reset(values);
27106
28898
  queryClient.invalidateQueries({ queryKey: ["agent-versions", agentId] });
27107
28899
  toast.success("Draft saved");
27108
28900
  } catch (error) {
@@ -27121,17 +28913,16 @@ function useAgentCmsForm(options) {
27121
28913
  setIsSubmitting(true);
27122
28914
  try {
27123
28915
  if (isEdit) {
27124
- const sharedParams = await buildSharedParams(values);
27125
- const editMemory = buildMemoryParams(values);
27126
- await updateStoredAgent.mutateAsync({
27127
- ...sharedParams,
27128
- memory: editMemory
27129
- });
27130
- const versionsResponse = await client.getStoredAgent(options.agentId).listVersions({ sortDirection: "DESC", perPage: 1 });
28916
+ const [agentDetails, versionsResponse] = await Promise.all([
28917
+ client.getStoredAgent(options.agentId).details(),
28918
+ client.getStoredAgent(options.agentId).listVersions({ sortDirection: "DESC", perPage: 1 })
28919
+ ]);
27131
28920
  const latestVersion = versionsResponse.versions[0];
27132
- if (latestVersion) {
27133
- await client.getStoredAgent(options.agentId).activateVersion(latestVersion.id);
28921
+ if (!latestVersion || latestVersion.id === agentDetails.activeVersionId) {
28922
+ toast.error("No draft changes to publish. Save a draft first.");
28923
+ return;
27134
28924
  }
28925
+ await client.getStoredAgent(options.agentId).activateVersion(latestVersion.id);
27135
28926
  await Promise.all([
27136
28927
  queryClient.invalidateQueries({ queryKey: ["agent-versions", agentId] }),
27137
28928
  queryClient.invalidateQueries({ queryKey: ["stored-agent", agentId] }),
@@ -27164,25 +28955,15 @@ function useAgentCmsForm(options) {
27164
28955
  } finally {
27165
28956
  setIsSubmitting(false);
27166
28957
  }
27167
- }, [
27168
- form,
27169
- isEdit,
27170
- client,
27171
- createStoredAgent,
27172
- updateStoredAgent,
27173
- options,
27174
- agentId,
27175
- buildSharedParams,
27176
- buildMemoryParams,
27177
- queryClient
27178
- ]);
28958
+ }, [form, isEdit, client, createStoredAgent, options, agentId, buildSharedParams, queryClient]);
27179
28959
  const watched = useWatch({ control: form.control });
27180
28960
  const canPublish = useMemo(() => {
27181
28961
  const identityDone = !!watched.name && !!watched.model?.provider && !!watched.model?.name;
27182
28962
  const instructionsDone = (watched.instructionBlocks ?? []).some((b) => b.content?.trim());
27183
28963
  return identityDone && instructionsDone;
27184
28964
  }, [watched.name, watched.model?.provider, watched.model?.name, watched.instructionBlocks]);
27185
- return { form, handlePublish, handleSaveDraft, isSubmitting, isSavingDraft, canPublish };
28965
+ const isDirty = form.formState.isDirty;
28966
+ return { form, handlePublish, handleSaveDraft, isSubmitting, isSavingDraft, canPublish, isDirty };
27186
28967
  }
27187
28968
 
27188
28969
  function AgentCmsFormShell({
@@ -27198,7 +28979,8 @@ function AgentCmsFormShell({
27198
28979
  currentPath,
27199
28980
  banner,
27200
28981
  children,
27201
- versionId
28982
+ versionId,
28983
+ rightPanel
27202
28984
  }) {
27203
28985
  return /* @__PURE__ */ jsx(
27204
28986
  AgentEditFormProvider,
@@ -27211,7 +28993,7 @@ function AgentCmsFormShell({
27211
28993
  handlePublish,
27212
28994
  handleSaveDraft,
27213
28995
  readOnly,
27214
- children: /* @__PURE__ */ jsxs(AgentsCmsLayout, { basePath, currentPath, versionId, children: [
28996
+ children: /* @__PURE__ */ jsxs(AgentsCmsLayout, { basePath, currentPath, versionId, rightPanel, children: [
27215
28997
  banner,
27216
28998
  children
27217
28999
  ] })
@@ -27219,6 +29001,61 @@ function AgentCmsFormShell({
27219
29001
  );
27220
29002
  }
27221
29003
 
29004
+ function formatTimestamp(isoString) {
29005
+ const date = new Date(isoString);
29006
+ return date.toLocaleDateString(void 0, {
29007
+ month: "short",
29008
+ day: "numeric",
29009
+ year: "numeric",
29010
+ hour: "2-digit",
29011
+ minute: "2-digit"
29012
+ });
29013
+ }
29014
+ function AgentVersionPanel({
29015
+ agentId,
29016
+ selectedVersionId,
29017
+ onVersionSelect,
29018
+ activeVersionId
29019
+ }) {
29020
+ const { data, isLoading } = useAgentVersions({
29021
+ agentId,
29022
+ params: { sortDirection: "DESC" }
29023
+ });
29024
+ const versions = data?.versions ?? [];
29025
+ const activeVersion = activeVersionId ? versions.find((v) => v.id === activeVersionId) : void 0;
29026
+ const activeVersionNumber = activeVersion?.versionNumber;
29027
+ return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col", children: [
29028
+ /* @__PURE__ */ jsx("div", { className: "px-3 py-3 border-b border-border1", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "font-medium text-neutral5", children: "Version history" }) }),
29029
+ /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 min-h-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-xs", className: "text-neutral2", children: "Loading versions..." }) }) : /* @__PURE__ */ jsx("ul", { className: "flex flex-col", children: versions.map((version) => {
29030
+ const isSelected = selectedVersionId === version.id || !selectedVersionId && version.id === versions[0]?.id;
29031
+ const isPublished = version.id === activeVersionId;
29032
+ const isDraft = activeVersionNumber !== void 0 && version.versionNumber > activeVersionNumber;
29033
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
29034
+ "button",
29035
+ {
29036
+ type: "button",
29037
+ onClick: () => onVersionSelect(version.id),
29038
+ className: cn(
29039
+ "w-full text-left px-3 py-2.5 text-sm transition-colors border-l-2",
29040
+ isSelected ? "bg-surface2 text-neutral5 border-accent1" : "border-transparent text-neutral3 hover:bg-surface3 hover:text-neutral5"
29041
+ ),
29042
+ children: [
29043
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
29044
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-inherit", children: [
29045
+ "v",
29046
+ version.versionNumber
29047
+ ] }),
29048
+ isPublished && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Published" }),
29049
+ isDraft && /* @__PURE__ */ jsx(Badge, { variant: "info", children: "Draft" })
29050
+ ] }),
29051
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-xs", className: "text-neutral2 mt-0.5", children: formatTimestamp(version.createdAt) })
29052
+ ]
29053
+ }
29054
+ ) }, version.id);
29055
+ }) }) })
29056
+ ] });
29057
+ }
29058
+
27222
29059
  const NameCell$3 = ({ row }) => {
27223
29060
  const { Link, paths } = useLinkComponent();
27224
29061
  const processor = row.original;
@@ -30740,7 +32577,7 @@ const useDatasetItemVersions = (datasetId, itemId) => {
30740
32577
  enabled: Boolean(datasetId) && Boolean(itemId)
30741
32578
  });
30742
32579
  };
30743
- const useDatasetItemVersion = (datasetId, itemId, datasetVersion) => {
32580
+ const useDatasetItemVersion = (datasetId, itemId, datasetVersion, latestVersion) => {
30744
32581
  const client = useMastraClient();
30745
32582
  return useQuery({
30746
32583
  queryKey: ["dataset-item-version", datasetId, itemId, datasetVersion],
@@ -30753,11 +32590,11 @@ const useDatasetItemVersion = (datasetId, itemId, datasetVersion) => {
30753
32590
  input: v.input,
30754
32591
  groundTruth: v.groundTruth,
30755
32592
  metadata: v.metadata,
30756
- validTo: v.validTo,
30757
- isDeleted: v.isDeleted,
32593
+ validTo: v.validTo ?? null,
32594
+ isDeleted: v.isDeleted ?? false,
30758
32595
  createdAt: v.createdAt,
30759
32596
  updatedAt: v.updatedAt,
30760
- isLatest: false
32597
+ isLatest: latestVersion != null ? datasetVersion === latestVersion : false
30761
32598
  };
30762
32599
  },
30763
32600
  enabled: Boolean(datasetId) && Boolean(itemId) && datasetVersion > 0
@@ -32404,6 +34241,52 @@ function DeleteDatasetDialog({
32404
34241
  ] }) });
32405
34242
  }
32406
34243
 
34244
+ function DatasetCombobox({
34245
+ value,
34246
+ onValueChange,
34247
+ placeholder = "Select a dataset...",
34248
+ searchPlaceholder = "Search datasets...",
34249
+ emptyText = "No datasets found.",
34250
+ className,
34251
+ disabled = false,
34252
+ variant = "default"
34253
+ }) {
34254
+ const { data, isLoading, isError, error } = useDatasets();
34255
+ const { navigate, paths } = useLinkComponent();
34256
+ useEffect(() => {
34257
+ if (isError) {
34258
+ const errorMessage = error instanceof Error ? error.message : "Failed to load datasets";
34259
+ toast.error(`Error loading datasets: ${errorMessage}`);
34260
+ }
34261
+ }, [isError, error]);
34262
+ const datasets = data?.datasets ?? [];
34263
+ const datasetOptions = datasets.map((d) => ({
34264
+ label: d.name,
34265
+ value: d.id
34266
+ }));
34267
+ const handleValueChange = (newDatasetId) => {
34268
+ if (onValueChange) {
34269
+ onValueChange(newDatasetId);
34270
+ } else if (newDatasetId && newDatasetId !== value) {
34271
+ navigate(paths.datasetLink(newDatasetId));
34272
+ }
34273
+ };
34274
+ return /* @__PURE__ */ jsx(
34275
+ Combobox,
34276
+ {
34277
+ options: datasetOptions,
34278
+ value,
34279
+ onValueChange: handleValueChange,
34280
+ placeholder: isLoading ? "Loading datasets..." : placeholder,
34281
+ searchPlaceholder,
34282
+ emptyText,
34283
+ className,
34284
+ disabled: disabled || isLoading || isError,
34285
+ variant
34286
+ }
34287
+ );
34288
+ }
34289
+
32407
34290
  function ItemListRoot({ children, className }) {
32408
34291
  return /* @__PURE__ */ jsx("div", { className: cn("grid grid-rows-[auto_1fr] overflow-y-auto", className), children });
32409
34292
  }
@@ -33188,24 +35071,18 @@ function ItemDetailToolbar({
33188
35071
  !isEditing && /* @__PURE__ */ jsxs(Fragment, { children: [
33189
35072
  /* @__PURE__ */ jsxs(Button, { variant: "standard", size: "default", href: `/datasets/${datasetId}/items/${itemId}`, as: Link, children: [
33190
35073
  /* @__PURE__ */ jsx(History, {}),
33191
- "History"
35074
+ "Versions"
33192
35075
  ] }),
33193
- /* @__PURE__ */ jsxs(ButtonsGroup, { spacing: "close", children: [
33194
- /* @__PURE__ */ jsxs(Button, { variant: "standard", size: "default", onClick: onEdit, children: [
33195
- /* @__PURE__ */ jsx(Pencil, {}),
33196
- "Edit"
33197
- ] }),
33198
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
33199
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "standard", size: "default", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(ChevronDownIcon, {}) }) }),
33200
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { align: "end", className: "w-48", children: [
33201
- /* @__PURE__ */ jsxs(DropdownMenu.Item, { onSelect: onDelete, className: "text-red-500 focus:text-red-400", children: [
33202
- /* @__PURE__ */ jsx(Trash2, {}),
33203
- /* @__PURE__ */ jsx("span", { children: "Delete Item" })
33204
- ] }),
33205
- /* @__PURE__ */ jsxs(DropdownMenu.Item, { disabled: true, children: [
33206
- /* @__PURE__ */ jsx(Copy, {}),
33207
- /* @__PURE__ */ jsx("span", { children: "Duplicate Item (Coming Soon)" })
33208
- ] })
35076
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
35077
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "standard", size: "default", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(EllipsisVerticalIcon, {}) }) }),
35078
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { align: "end", className: "w-48", children: [
35079
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, { onSelect: onEdit, children: [
35080
+ /* @__PURE__ */ jsx(Pencil, {}),
35081
+ "Edit"
35082
+ ] }),
35083
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, { onSelect: onDelete, className: "text-red-500 focus:text-red-400", children: [
35084
+ /* @__PURE__ */ jsx(Trash2, {}),
35085
+ "Delete Item"
33209
35086
  ] })
33210
35087
  ] })
33211
35088
  ] })
@@ -36137,9 +38014,9 @@ function ExperimentResultPanel({
36137
38014
  onClose,
36138
38015
  onShowTrace
36139
38016
  }) {
36140
- const hasError = Boolean(result.error);
36141
- const inputStr = formatValue$1(result.input);
36142
- const outputStr = formatValue$1(result.output);
38017
+ const hasError = Boolean(result?.error);
38018
+ const inputStr = formatValue$1(result?.input);
38019
+ const outputStr = formatValue$1(result?.output);
36143
38020
  return /* @__PURE__ */ jsxs(Fragment, { children: [
36144
38021
  /* @__PURE__ */ jsxs(ListAndDetails.ColumnToolbar, { children: [
36145
38022
  /* @__PURE__ */ jsx(
@@ -36172,6 +38049,15 @@ function ExperimentResultPanel({
36172
38049
  result.itemId
36173
38050
  ] }) })
36174
38051
  ] }) }),
38052
+ hasError && /* @__PURE__ */ jsxs(Notice, { variant: "destructive", children: [
38053
+ /* @__PURE__ */ jsx(OctagonAlertIcon, {}),
38054
+ /* @__PURE__ */ jsxs(Notice.Message, { children: [
38055
+ /* @__PURE__ */ jsx("strong", { children: "Error: " }),
38056
+ formatValue$1(
38057
+ result?.error && typeof result.error === "object" ? result.error.message : result?.error
38058
+ )
38059
+ ] })
38060
+ ] }),
36175
38061
  /* @__PURE__ */ jsx(SideDialog.CodeSection, { title: "Input", icon: /* @__PURE__ */ jsx(FileCodeIcon, {}), codeStr: inputStr }),
36176
38062
  /* @__PURE__ */ jsx(SideDialog.CodeSection, { title: "Output", icon: /* @__PURE__ */ jsx(FileOutputIcon, {}), codeStr: outputStr }),
36177
38063
  /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
@@ -36180,16 +38066,6 @@ function ExperimentResultPanel({
36180
38066
  " Created"
36181
38067
  ] }),
36182
38068
  /* @__PURE__ */ jsx("p", { className: "text-sm text-neutral4", children: format$1(new Date(result.createdAt), "MMM d, yyyy 'at' h:mm a") })
36183
- ] }),
36184
- hasError && /* @__PURE__ */ jsxs(Section, { children: [
36185
- /* @__PURE__ */ jsxs(Section.Header, { children: [
36186
- /* @__PURE__ */ jsxs(Section.Heading, { children: [
36187
- /* @__PURE__ */ jsx(AlertCircleIcon, {}),
36188
- " Error"
36189
- ] }),
36190
- /* @__PURE__ */ jsx(CopyButton, { content: result.error || "" })
36191
- ] }),
36192
- /* @__PURE__ */ jsx("div", { className: "bg-black/20 p-4 overflow-hidden rounded-xl border border-white/10 text-neutral4 text-ui-md", children: /* @__PURE__ */ jsx("pre", { className: "text-wrap font-mono text-sm whitespace-pre-wrap break-all", children: result.error }) })
36193
38069
  ] })
36194
38070
  ] })
36195
38071
  ] });
@@ -37289,8 +39165,9 @@ function DatasetItemVersionsPanel({
37289
39165
  }
37290
39166
  };
37291
39167
  const columnsToRender = isSelectionActive ? versionsListColumnsWithCheckbox : versionsListColumns;
37292
- return /* @__PURE__ */ jsxs(Column, { className: "min-w-[20rem]", children: [
39168
+ return /* @__PURE__ */ jsxs(Column, { className: "min-w-[17rem]", children: [
37293
39169
  isSelectionActive ? /* @__PURE__ */ jsx(Column.Toolbar, { className: "grid justify-stretch gap-3 w-full", children: /* @__PURE__ */ jsxs(ButtonsGroup, { children: [
39170
+ /* @__PURE__ */ jsx(Button, { variant: "standard", size: "default", onClick: handleCancelSelection, children: "Cancel" }),
37294
39171
  /* @__PURE__ */ jsx(
37295
39172
  ButtonWithTooltip,
37296
39173
  {
@@ -37298,14 +39175,14 @@ function DatasetItemVersionsPanel({
37298
39175
  size: "default",
37299
39176
  disabled: selectedIds.size !== 2,
37300
39177
  onClick: handleExecuteCompare,
37301
- tooltipContent: selectedIds.size !== 2 ? "Select exactly 2 versions to compare" : void 0,
37302
- children: "Compare Versions"
39178
+ tooltipContent: selectedIds.size !== 2 ? "Check 2 versions to compare" : void 0,
39179
+ className: "grow",
39180
+ children: "Compare Selected"
37303
39181
  }
37304
- ),
37305
- /* @__PURE__ */ jsx(Button, { variant: "standard", size: "default", onClick: handleCancelSelection, children: "Cancel" })
37306
- ] }) }) : /* @__PURE__ */ jsx(Column.Toolbar, { children: /* @__PURE__ */ jsxs(Button, { variant: "standard", size: "default", onClick: handleCompareClick, children: [
37307
- /* @__PURE__ */ jsx(ScaleIcon, {}),
37308
- " Compare"
39182
+ )
39183
+ ] }) }) : /* @__PURE__ */ jsx(Column.Toolbar, { children: /* @__PURE__ */ jsxs(Button, { variant: "standard", size: "default", onClick: handleCompareClick, className: "w-full", children: [
39184
+ /* @__PURE__ */ jsx(GitCompareIcon, {}),
39185
+ " Compare Versions"
37309
39186
  ] }) }),
37310
39187
  isLoading ? /* @__PURE__ */ jsx(DatasetItemVersionsListSkeleton, {}) : /* @__PURE__ */ jsxs(ItemList, { children: [
37311
39188
  /* @__PURE__ */ jsx("div", { className: "grid grid-rows-[1fr_auto] gap-4", children: /* @__PURE__ */ jsx(ItemList.Header, { columns: columnsToRender, children: columnsToRender.map(
@@ -37313,7 +39190,7 @@ function DatasetItemVersionsPanel({
37313
39190
  ) }) }),
37314
39191
  /* @__PURE__ */ jsx(ItemList.Scroller, { children: /* @__PURE__ */ jsx(ItemList.Items, { children: versions?.map((item, index) => {
37315
39192
  const versionKey = String(item.datasetVersion);
37316
- const createdAtDate = typeof item.createdAt === "string" ? new Date(item.createdAt) : item.createdAt;
39193
+ const versionDate = typeof item.updatedAt === "string" ? new Date(item.updatedAt) : item.updatedAt;
37317
39194
  return /* @__PURE__ */ jsxs(
37318
39195
  ItemList.Row,
37319
39196
  {
@@ -37323,11 +39200,14 @@ function DatasetItemVersionsPanel({
37323
39200
  Checkbox,
37324
39201
  {
37325
39202
  checked: selectedIds.has(versionKey),
39203
+ disabled: item.isDeleted,
37326
39204
  onCheckedChange: () => {
37327
39205
  },
37328
39206
  onClick: (e) => {
37329
39207
  e.stopPropagation();
37330
- handleToggleSelection(versionKey);
39208
+ if (!item.isDeleted) {
39209
+ handleToggleSelection(versionKey);
39210
+ }
37331
39211
  },
37332
39212
  "aria-label": `Select version ${item.datasetVersion}`
37333
39213
  }
@@ -37340,13 +39220,18 @@ function DatasetItemVersionsPanel({
37340
39220
  isSelected: isSelectionActive ? selectedIds.has(versionKey) : isVersionSelected(item),
37341
39221
  onClick: () => handleVersionClick(item),
37342
39222
  className: "py-3",
37343
- children: /* @__PURE__ */ jsxs(ItemList.FlexCell, { className: "w-full text-neutral flex gap-4 items-baseline text-neutral3", children: [
37344
- /* @__PURE__ */ jsxs("strong", { className: "min-w-8", children: [
37345
- "v",
37346
- item.datasetVersion
39223
+ children: /* @__PURE__ */ jsxs(ItemList.FlexCell, { className: "w-full text-neutral grid text-neutral3", children: [
39224
+ /* @__PURE__ */ jsxs("div", { className: "flex", children: [
39225
+ /* @__PURE__ */ jsxs("strong", { className: "min-w-11", children: [
39226
+ "v",
39227
+ item.datasetVersion
39228
+ ] }),
39229
+ /* @__PURE__ */ jsx("em", { children: versionDate ? format(versionDate, "MMM d, yyyy HH:mm") : null })
37347
39230
  ] }),
37348
- /* @__PURE__ */ jsx("em", { children: createdAtDate ? format(createdAtDate, "MMM d, yyyy HH:mm") : null }),
37349
- item.isLatest && /* @__PURE__ */ jsx("span", { className: "ml-auto inline-block text-neutral4 text-xs p-1 px-2 leading-none rounded-sm bg-cyan-800", children: "Latest" })
39231
+ (item.isLatest || item.isDeleted) && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pl-11 ", children: [
39232
+ item.isLatest && /* @__PURE__ */ jsx("span", { className: "inline-block text-neutral4 text-xs p-1 px-2 leading-none rounded-sm bg-cyan-900", children: "Latest" }),
39233
+ item.isDeleted && /* @__PURE__ */ jsx("span", { className: "inline-block text-neutral4 text-xs p-1 px-2 leading-none rounded-sm bg-red-900", children: "Deleted" })
39234
+ ] })
37350
39235
  ] })
37351
39236
  }
37352
39237
  )
@@ -37928,6 +39813,83 @@ function PageHeader({ title, description, icon, className }) {
37928
39813
  ] });
37929
39814
  }
37930
39815
 
39816
+ const diffOverrides = EditorView.theme({
39817
+ "&.cm-editor .cm-changedLine": {
39818
+ backgroundColor: "transparent",
39819
+ backgroundImage: "none",
39820
+ borderLeft: "none"
39821
+ },
39822
+ "&.cm-editor .cm-changedText": {
39823
+ backgroundImage: "none",
39824
+ backgroundColor: "#880000",
39825
+ padding: "1px 5px",
39826
+ display: "inline-block",
39827
+ borderRadius: "4px"
39828
+ },
39829
+ "&.cm-editor .cm-changedText, &.cm-editor .cm-changedText *": {
39830
+ color: "white"
39831
+ },
39832
+ "&.cm-editor .cm-line": {
39833
+ lineHeight: "1.5",
39834
+ opacity: "0.5"
39835
+ },
39836
+ "&.cm-editor .cm-line.cm-changedLine": {
39837
+ opacity: "1"
39838
+ },
39839
+ "&.cm-editor .cm-gutters": {
39840
+ display: "none"
39841
+ }
39842
+ });
39843
+ const theme = draculaInit({
39844
+ settings: {
39845
+ fontFamily: "var(--geist-mono)",
39846
+ fontSize: "0.8125rem",
39847
+ lineHighlight: "transparent",
39848
+ gutterBackground: "transparent",
39849
+ gutterForeground: "#939393",
39850
+ background: "transparent"
39851
+ },
39852
+ styles: [{ tag: [tags.className, tags.propertyName] }]
39853
+ });
39854
+ function CodeDiff({ codeA, codeB }) {
39855
+ const containerRef = useRef(null);
39856
+ const viewRef = useRef(null);
39857
+ useEffect(() => {
39858
+ if (!containerRef.current) return;
39859
+ if (viewRef.current) {
39860
+ viewRef.current.destroy();
39861
+ }
39862
+ const extensions = [json(), theme, diffOverrides, EditorView.lineWrapping, EditorState.readOnly.of(true)];
39863
+ const mergeView = new MergeView({
39864
+ parent: containerRef.current,
39865
+ a: {
39866
+ doc: codeA,
39867
+ extensions
39868
+ },
39869
+ b: {
39870
+ doc: codeB,
39871
+ extensions
39872
+ },
39873
+ collapseUnchanged: { margin: 3, minSize: 4 }
39874
+ });
39875
+ viewRef.current = mergeView;
39876
+ return () => {
39877
+ mergeView.destroy();
39878
+ viewRef.current = null;
39879
+ };
39880
+ }, [codeA, codeB]);
39881
+ return /* @__PURE__ */ jsxs("div", { className: "relative overflow-auto rounded-xl border border-white/10 bg-black/20", children: [
39882
+ /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 top-0 h-full w-px bg-white/10 z-10" }),
39883
+ /* @__PURE__ */ jsx(
39884
+ "div",
39885
+ {
39886
+ ref: containerRef,
39887
+ className: "[&_.cm-mergeViewEditor]:flex-1 [&_.cm-editor]:bg-transparent [&_.cm-editor]:p-6 [&_.cm-gutters]:bg-transparent"
39888
+ }
39889
+ )
39890
+ ] });
39891
+ }
39892
+
37931
39893
  const PlaygroundQueryClient = ({ children, options }) => {
37932
39894
  const queryClient = new QueryClient(options);
37933
39895
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children });
@@ -39440,180 +41402,6 @@ function ReferenceViewerDialog({
39440
41402
  ] });
39441
41403
  }
39442
41404
 
39443
- const useSearchSkillsSh = (workspaceId) => {
39444
- const client = useMastraClient();
39445
- return useMutation({
39446
- mutationFn: async (query) => {
39447
- if (!workspaceId) {
39448
- throw new Error("Workspace ID is required");
39449
- }
39450
- const baseUrl = client.options.baseUrl || "";
39451
- const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/search?q=${encodeURIComponent(query)}&limit=10`;
39452
- const response = await fetch(url);
39453
- if (!response.ok) {
39454
- throw new Error(`Failed to search skills: ${response.statusText}`);
39455
- }
39456
- return response.json().catch(() => {
39457
- throw new Error("Invalid response from server");
39458
- });
39459
- }
39460
- });
39461
- };
39462
- const usePopularSkillsSh = (workspaceId) => {
39463
- const client = useMastraClient();
39464
- return useQuery({
39465
- queryKey: ["skills-sh", "popular", workspaceId],
39466
- queryFn: async () => {
39467
- if (!workspaceId) {
39468
- throw new Error("Workspace ID is required");
39469
- }
39470
- const baseUrl = client.options.baseUrl || "";
39471
- const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/popular?limit=10&offset=0`;
39472
- const response = await fetch(url);
39473
- if (!response.ok) {
39474
- throw new Error(`Failed to fetch popular skills: ${response.statusText}`);
39475
- }
39476
- return response.json().catch(() => {
39477
- throw new Error("Invalid response from server");
39478
- });
39479
- },
39480
- staleTime: 5 * 60 * 1e3,
39481
- // 5 minutes
39482
- enabled: !!workspaceId
39483
- });
39484
- };
39485
- const useSkillPreview = (workspaceId, owner, repo, skillPath, options) => {
39486
- const client = useMastraClient();
39487
- return useQuery({
39488
- queryKey: ["skills-sh", "preview", workspaceId, owner, repo, skillPath],
39489
- queryFn: async () => {
39490
- if (!workspaceId || !owner || !repo || !skillPath) {
39491
- throw new Error("workspaceId, owner, repo, and skillPath are required");
39492
- }
39493
- const baseUrl = client.options.baseUrl || "";
39494
- const params = new URLSearchParams({ owner, repo, path: skillPath });
39495
- const url = `${baseUrl}/api/workspaces/${workspaceId}/skills-sh/preview?${params}`;
39496
- const response = await fetch(url);
39497
- if (!response.ok) {
39498
- throw new Error(`Failed to fetch preview: ${response.statusText}`);
39499
- }
39500
- const data = await response.json().catch(() => {
39501
- throw new Error("Invalid response from server");
39502
- });
39503
- return data.content;
39504
- },
39505
- enabled: options?.enabled !== false && !!workspaceId && !!owner && !!repo && !!skillPath,
39506
- retry: false
39507
- });
39508
- };
39509
- const useInstallSkill = () => {
39510
- const client = useMastraClient();
39511
- const queryClient = useQueryClient();
39512
- return useMutation({
39513
- mutationFn: async (params) => {
39514
- const [owner, repo] = params.repository.split("/");
39515
- if (!owner || !repo) {
39516
- throw new Error("Invalid repository format. Expected owner/repo");
39517
- }
39518
- const baseUrl = client.options.baseUrl || "";
39519
- const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/install`;
39520
- const body = { owner, repo, skillName: params.skillName };
39521
- if (params.mount) {
39522
- body.mount = params.mount;
39523
- }
39524
- const response = await fetch(url, {
39525
- method: "POST",
39526
- headers: { "Content-Type": "application/json" },
39527
- body: JSON.stringify(body)
39528
- });
39529
- if (!response.ok) {
39530
- const error = await response.json().catch(() => ({}));
39531
- throw new Error(error.error || error.message || `Failed to install skill: ${response.statusText}`);
39532
- }
39533
- return response.json().catch(() => {
39534
- throw new Error("Invalid response from server");
39535
- });
39536
- },
39537
- onSuccess: (_, variables) => {
39538
- queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
39539
- }
39540
- });
39541
- };
39542
- const useUpdateSkills = () => {
39543
- const client = useMastraClient();
39544
- const queryClient = useQueryClient();
39545
- return useMutation({
39546
- mutationFn: async (params) => {
39547
- const baseUrl = client.options.baseUrl || "";
39548
- const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/update`;
39549
- const response = await fetch(url, {
39550
- method: "POST",
39551
- headers: { "Content-Type": "application/json" },
39552
- body: JSON.stringify({ skillName: params.skillName })
39553
- });
39554
- if (!response.ok) {
39555
- const error = await response.json().catch(() => ({}));
39556
- throw new Error(error.error || error.message || `Failed to update skill: ${response.statusText}`);
39557
- }
39558
- return response.json().catch(() => {
39559
- throw new Error("Invalid response from server");
39560
- });
39561
- },
39562
- onSuccess: (_, variables) => {
39563
- queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
39564
- }
39565
- });
39566
- };
39567
- const useRemoveSkill = () => {
39568
- const client = useMastraClient();
39569
- const queryClient = useQueryClient();
39570
- return useMutation({
39571
- mutationFn: async (params) => {
39572
- const baseUrl = client.options.baseUrl || "";
39573
- const url = `${baseUrl}/api/workspaces/${params.workspaceId}/skills-sh/remove`;
39574
- const response = await fetch(url, {
39575
- method: "POST",
39576
- headers: { "Content-Type": "application/json" },
39577
- body: JSON.stringify({ skillName: params.skillName })
39578
- });
39579
- if (!response.ok) {
39580
- const error = await response.json().catch(() => ({}));
39581
- throw new Error(error.error || error.message || `Failed to remove skill: ${response.statusText}`);
39582
- }
39583
- return response.json().catch(() => {
39584
- throw new Error("Invalid response from server");
39585
- });
39586
- },
39587
- onSuccess: (_, variables) => {
39588
- queryClient.invalidateQueries({ queryKey: ["workspace", "skills", variables.workspaceId] });
39589
- }
39590
- });
39591
- };
39592
- function parseSkillSource(topSource, skillName) {
39593
- let cleanSource = topSource.replace(/^https?:\/\//, "");
39594
- cleanSource = cleanSource.replace(/^github\.com\//, "");
39595
- cleanSource = cleanSource.replace(/\/$/, "");
39596
- const parts = cleanSource.split("/").filter(Boolean);
39597
- if (parts.length < 2) {
39598
- return null;
39599
- }
39600
- const owner = parts[0];
39601
- const repo = parts[1];
39602
- let skillPath;
39603
- if (parts.length > 2) {
39604
- skillPath = parts.slice(2).join("/");
39605
- } else if (skillName) {
39606
- skillPath = skillName;
39607
- } else {
39608
- return null;
39609
- }
39610
- return {
39611
- owner,
39612
- repo,
39613
- skillPath
39614
- };
39615
- }
39616
-
39617
41405
  function getSkillUniqueId(skill) {
39618
41406
  return `${skill.topSource}/${skill.name}`;
39619
41407
  }
@@ -39876,314 +41664,6 @@ function AddSkillDialog({
39876
41664
  ] }) });
39877
41665
  }
39878
41666
 
39879
- const useWorkspaceInfo = (workspaceId) => {
39880
- const client = useMastraClient();
39881
- return useQuery({
39882
- queryKey: ["workspace", "info", workspaceId],
39883
- queryFn: async () => {
39884
- if (!isWorkspaceV1Supported(client)) {
39885
- throw new Error("Workspace v1 not supported by core or client");
39886
- }
39887
- if (!workspaceId) {
39888
- throw new Error("workspaceId is required");
39889
- }
39890
- const workspace = client.getWorkspace(workspaceId);
39891
- return workspace.info();
39892
- },
39893
- enabled: !!workspaceId && isWorkspaceV1Supported(client),
39894
- retry: shouldRetryWorkspaceQuery
39895
- });
39896
- };
39897
- const useWorkspaces = () => {
39898
- const client = useMastraClient();
39899
- return useQuery({
39900
- queryKey: ["workspaces"],
39901
- queryFn: async () => {
39902
- if (!isWorkspaceV1Supported(client)) {
39903
- throw new Error("Workspace v1 not supported by core or client");
39904
- }
39905
- return client.listWorkspaces();
39906
- },
39907
- retry: shouldRetryWorkspaceQuery
39908
- });
39909
- };
39910
- const useWorkspaceFiles = (path, options) => {
39911
- const client = useMastraClient();
39912
- return useQuery({
39913
- queryKey: ["workspace", "files", path, options?.recursive, options?.workspaceId],
39914
- queryFn: async () => {
39915
- if (!isWorkspaceV1Supported(client)) {
39916
- throw new Error("Workspace v1 not supported by core or client");
39917
- }
39918
- if (!options?.workspaceId) {
39919
- throw new Error("workspaceId is required");
39920
- }
39921
- const workspace = client.getWorkspace(options.workspaceId);
39922
- return workspace.listFiles(path, options?.recursive);
39923
- },
39924
- enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
39925
- retry: shouldRetryWorkspaceQuery
39926
- });
39927
- };
39928
- const useWorkspaceFile = (path, options) => {
39929
- const client = useMastraClient();
39930
- return useQuery({
39931
- queryKey: ["workspace", "file", path, options?.workspaceId],
39932
- queryFn: async () => {
39933
- if (!isWorkspaceV1Supported(client)) {
39934
- throw new Error("Workspace v1 not supported by core or client");
39935
- }
39936
- if (!options?.workspaceId) {
39937
- throw new Error("workspaceId is required");
39938
- }
39939
- const workspace = client.getWorkspace(options.workspaceId);
39940
- return workspace.readFile(path, options?.encoding);
39941
- },
39942
- enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
39943
- retry: shouldRetryWorkspaceQuery
39944
- });
39945
- };
39946
- const useWorkspaceFileStat = (path, options) => {
39947
- const client = useMastraClient();
39948
- return useQuery({
39949
- queryKey: ["workspace", "stat", path, options?.workspaceId],
39950
- queryFn: async () => {
39951
- if (!isWorkspaceV1Supported(client)) {
39952
- throw new Error("Workspace v1 not supported by core or client");
39953
- }
39954
- if (!options?.workspaceId) {
39955
- throw new Error("workspaceId is required");
39956
- }
39957
- const workspace = client.getWorkspace(options.workspaceId);
39958
- return workspace.stat(path);
39959
- },
39960
- enabled: options?.enabled !== false && !!path && !!options?.workspaceId && isWorkspaceV1Supported(client),
39961
- retry: shouldRetryWorkspaceQuery
39962
- });
39963
- };
39964
- const useWriteWorkspaceFile = () => {
39965
- const client = useMastraClient();
39966
- const queryClient = useQueryClient();
39967
- return useMutation({
39968
- mutationFn: async (params) => {
39969
- if (!isWorkspaceV1Supported(client)) {
39970
- throw new Error("Workspace v1 not supported by core or client");
39971
- }
39972
- const workspace = client.getWorkspace(params.workspaceId);
39973
- return workspace.writeFile(params.path, params.content, {
39974
- encoding: params.encoding,
39975
- recursive: params.recursive ?? true
39976
- });
39977
- },
39978
- onSuccess: (_, variables) => {
39979
- const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
39980
- queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
39981
- queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
39982
- }
39983
- });
39984
- };
39985
- const useWriteWorkspaceFileFromFile = () => {
39986
- const client = useMastraClient();
39987
- const queryClient = useQueryClient();
39988
- return useMutation({
39989
- mutationFn: async (params) => {
39990
- if (!isWorkspaceV1Supported(client)) {
39991
- throw new Error("Workspace v1 not supported by core or client");
39992
- }
39993
- const arrayBuffer = await params.file.arrayBuffer();
39994
- const base64 = btoa(new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), ""));
39995
- const workspace = client.getWorkspace(params.workspaceId);
39996
- return workspace.writeFile(params.path, base64, {
39997
- encoding: "base64",
39998
- recursive: params.recursive ?? true
39999
- });
40000
- },
40001
- onSuccess: (_, variables) => {
40002
- const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
40003
- queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
40004
- queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
40005
- }
40006
- });
40007
- };
40008
- const useDeleteWorkspaceFile = () => {
40009
- const client = useMastraClient();
40010
- const queryClient = useQueryClient();
40011
- return useMutation({
40012
- mutationFn: async (params) => {
40013
- if (!isWorkspaceV1Supported(client)) {
40014
- throw new Error("Workspace v1 not supported by core or client");
40015
- }
40016
- const workspace = client.getWorkspace(params.workspaceId);
40017
- return workspace.delete(params.path, {
40018
- recursive: params.recursive,
40019
- force: params.force
40020
- });
40021
- },
40022
- onSuccess: (_, variables) => {
40023
- const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
40024
- queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
40025
- queryClient.invalidateQueries({ queryKey: ["workspace", "file", variables.path] });
40026
- }
40027
- });
40028
- };
40029
- const useCreateWorkspaceDirectory = () => {
40030
- const client = useMastraClient();
40031
- const queryClient = useQueryClient();
40032
- return useMutation({
40033
- mutationFn: async (params) => {
40034
- if (!isWorkspaceV1Supported(client)) {
40035
- throw new Error("Workspace v1 not supported by core or client");
40036
- }
40037
- const workspace = client.getWorkspace(params.workspaceId);
40038
- return workspace.mkdir(params.path, params.recursive);
40039
- },
40040
- onSuccess: (_, variables) => {
40041
- const parentPath = variables.path.split("/").slice(0, -1).join("/") || "/";
40042
- queryClient.invalidateQueries({ queryKey: ["workspace", "files", parentPath] });
40043
- }
40044
- });
40045
- };
40046
- const useSearchWorkspace = () => {
40047
- const client = useMastraClient();
40048
- return useMutation({
40049
- mutationFn: async (params) => {
40050
- if (!isWorkspaceV1Supported(client)) {
40051
- throw new Error("Workspace v1 not supported by core or client");
40052
- }
40053
- const workspace = client.getWorkspace(params.workspaceId);
40054
- return workspace.search({
40055
- query: params.query,
40056
- topK: params.topK,
40057
- mode: params.mode,
40058
- minScore: params.minScore
40059
- });
40060
- }
40061
- });
40062
- };
40063
- const useIndexWorkspaceContent = () => {
40064
- const client = useMastraClient();
40065
- return useMutation({
40066
- mutationFn: async (params) => {
40067
- if (!isWorkspaceV1Supported(client)) {
40068
- throw new Error("Workspace v1 not supported by core or client");
40069
- }
40070
- const workspace = client.getWorkspace(params.workspaceId);
40071
- return workspace.index({
40072
- path: params.path,
40073
- content: params.content,
40074
- metadata: params.metadata
40075
- });
40076
- }
40077
- });
40078
- };
40079
-
40080
- const useWorkspaceSkills = (options) => {
40081
- const client = useMastraClient();
40082
- return useQuery({
40083
- queryKey: ["workspace", "skills", options?.workspaceId],
40084
- queryFn: async () => {
40085
- if (!isWorkspaceV1Supported(client)) {
40086
- throw new Error("Workspace v1 not supported by core or client");
40087
- }
40088
- if (!options?.workspaceId) {
40089
- throw new Error("workspaceId is required");
40090
- }
40091
- const workspace = client.getWorkspace(options.workspaceId);
40092
- return workspace.listSkills();
40093
- },
40094
- enabled: !!options?.workspaceId && isWorkspaceV1Supported(client),
40095
- retry: shouldRetryWorkspaceQuery
40096
- });
40097
- };
40098
- const useWorkspaceSkill = (skillName, options) => {
40099
- const client = useMastraClient();
40100
- return useQuery({
40101
- queryKey: ["workspace", "skills", skillName, options?.workspaceId],
40102
- queryFn: async () => {
40103
- if (!isWorkspaceV1Supported(client)) {
40104
- throw new Error("Workspace v1 not supported by core or client");
40105
- }
40106
- if (!options?.workspaceId) {
40107
- throw new Error("workspaceId is required");
40108
- }
40109
- const workspace = client.getWorkspace(options.workspaceId);
40110
- const skill = workspace.getSkill(skillName);
40111
- return skill.details();
40112
- },
40113
- enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
40114
- retry: shouldRetryWorkspaceQuery
40115
- });
40116
- };
40117
- const useWorkspaceSkillReferences = (skillName, options) => {
40118
- const client = useMastraClient();
40119
- return useQuery({
40120
- queryKey: ["workspace", "skills", skillName, "references", options?.workspaceId],
40121
- queryFn: async () => {
40122
- if (!isWorkspaceV1Supported(client)) {
40123
- throw new Error("Workspace v1 not supported by core or client");
40124
- }
40125
- if (!options?.workspaceId) {
40126
- throw new Error("workspaceId is required");
40127
- }
40128
- const workspace = client.getWorkspace(options.workspaceId);
40129
- const skill = workspace.getSkill(skillName);
40130
- return skill.listReferences();
40131
- },
40132
- enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
40133
- retry: shouldRetryWorkspaceQuery
40134
- });
40135
- };
40136
- const useWorkspaceSkillReference = (skillName, referencePath, options) => {
40137
- const client = useMastraClient();
40138
- return useQuery({
40139
- queryKey: ["workspace", "skills", skillName, "references", referencePath, options?.workspaceId],
40140
- queryFn: async () => {
40141
- if (!isWorkspaceV1Supported(client)) {
40142
- throw new Error("Workspace v1 not supported by core or client");
40143
- }
40144
- if (!options?.workspaceId) {
40145
- throw new Error("workspaceId is required");
40146
- }
40147
- const workspace = client.getWorkspace(options.workspaceId);
40148
- const skill = workspace.getSkill(skillName);
40149
- return skill.getReference(referencePath);
40150
- },
40151
- enabled: options?.enabled !== false && !!skillName && !!referencePath && !!options?.workspaceId && isWorkspaceV1Supported(client),
40152
- retry: shouldRetryWorkspaceQuery
40153
- });
40154
- };
40155
- const useSearchWorkspaceSkills = () => {
40156
- const client = useMastraClient();
40157
- return useMutation({
40158
- mutationFn: async (params) => {
40159
- if (!isWorkspaceV1Supported(client)) {
40160
- throw new Error("Workspace v1 not supported by core or client");
40161
- }
40162
- const workspace = client.getWorkspace(params.workspaceId);
40163
- return workspace.searchSkills(params);
40164
- }
40165
- });
40166
- };
40167
- const useAgentSkill = (agentId, skillName, options) => {
40168
- const client = useMastraClient();
40169
- return useQuery({
40170
- queryKey: ["agents", agentId, "skills", skillName, options?.workspaceId],
40171
- queryFn: async () => {
40172
- if (!isWorkspaceV1Supported(client)) {
40173
- throw new Error("Workspace v1 not supported by core or client");
40174
- }
40175
- if (!options?.workspaceId) {
40176
- throw new Error("workspaceId is required");
40177
- }
40178
- const workspace = client.getWorkspace(options.workspaceId);
40179
- const skill = workspace.getSkill(skillName);
40180
- return skill.details();
40181
- },
40182
- enabled: options?.enabled !== false && !!agentId && !!skillName && !!options?.workspaceId && isWorkspaceV1Supported(client),
40183
- retry: shouldRetryWorkspaceQuery
40184
- });
40185
- };
40186
-
40187
41667
  const useMastraPlatform = () => {
40188
41668
  const mastraPlatformEndpoint = window.MASTRA_CLOUD_API_ENDPOINT;
40189
41669
  const isMastraPlatform = Boolean(mastraPlatformEndpoint);
@@ -40416,5 +41896,5 @@ const NavigationCommand = () => {
40416
41896
  );
40417
41897
  };
40418
41898
 
40419
- export { AGENT_CMS_SECTIONS, ActionsMenu, ActivatedSkillsProvider, AddField, AddItemDialog, AddItemsToDatasetDialog, AddSkillDialog, AgentCMSBlock, AgentCMSBlocks, AgentChat, AgentCmsBottomBar, AgentCmsFormShell, AgentCmsSidebar, AgentCoinIcon, AgentCombobox, AgentEditFormProvider, AgentEditLayout, AgentEntityHeader, AgentIcon, AgentInformation, AgentInformationLayout, AgentInformationTabLayout, AgentLayout, AgentMemory, AgentMetadata, AgentMetadataCombinedProcessorList, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataSkillList, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWorkspaceToolsList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentSourceIcon, AgentToolPanel, AgentVersionCombobox, AgentsCmsLayout, AgentsPage, AgentsSection, AgentsTable, AiIcon, Alert, AlertDescription, AlertDialog, AlertTitle, ApiIcon, AutoForm, Avatar, Badge, BranchIcon, Breadcrumb$1 as Breadcrumb, Button, ButtonWithTooltip, ButtonsGroup, CSVImportDialog, Cell, ChatThreads, CheckIcon, Checkbox, ChevronIcon, CodeEditor, Collapsible, CollapsibleContent, CollapsibleTrigger, Column, Columns, CombinedButtons, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CommitIcon, ComparisonView, ComposerModelSwitcher, ContentBlock, ContentBlocks, CopyButton, CreateDatasetDialog, CreateDatasetFromItemsDialog, CrossIcon, Crumb, DatasetCompareVersionToolbar, DatasetCompareVersionsList, DatasetExperiments, DatasetItemContent, DatasetItemHeader, DatasetItemVersionsPanel, DatasetItemsList, DatasetPageContent, DatasetVersionsPanel, DatasetsTable, DatePicker, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeleteDatasetDialog, DeploymentIcon, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DisplayConditionsDialog, DividerIcon, DocsIcon, DuplicateDatasetDialog, DynamicForm, EditDatasetDialog, EditModeContent, ElementSelect, EmptyDatasetsTable, EmptyState$1 as EmptyState, Entity, EntityAccordionItem, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EntryList, EntryListSkeleton, EnvIcon, ExperimentPageHeader, ExperimentResultSpanPane, ExperimentResultTracePanel, ExperimentResultsListAndDetails, ExperimentStats, ExperimentTriggerDialog, Field, FieldDescription, FieldList, FieldName, FieldNullable, FieldOptional, FieldRemove, FieldType, FileBrowser, FileViewer, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InformationPage, Input, InputField, InstructionBlocksPage, IntegrationToolsSection, ItemList, ItemListSkeleton, ItemPageToolbar, JSONImportDialog, JSONSchemaForm, JudgeIcon, Kbd, KeyValueList, LLMModels, LLMProviders, Label, LatencyIcon, LinkComponentProvider, ListAndDetails, LogoWithoutText, LogsIcon, MCPClientCreateContent, MCPClientEditLayout, MCPClientFormSidebar, MCPClientList, MCPClientToolPreview, MCPDetail, MCPServerCombobox, MCPTable, MCPToolPanel, MainContentContent, MainContentLayout, MainHeader, MainSidebar, MainSidebarProvider, MarkdownRenderer, MastraPackagesInfo, MastraVersionFooter, McpCoinIcon, McpServerIcon, MemoryIcon, MemoryPage, MemorySearch, MemorySection, MultiCombobox, NavigationCommand, NestedFields, Notice, Notification, OPERATORS, OPERATOR_LABELS, ObservationalMemoryProvider, OpenAIIcon, PageHeader, PlaygroundConfigGuard, PlaygroundQueryClient, Popover, PopoverContent, PopoverTrigger, ProcessStepList, ProcessStepListItem, ProcessStepProgressBar, ProcessorCombobox, ProcessorIcon, ProcessorPanel, ProcessorTable, PromptIcon, ProviderLogo, RadioGroup, RadioGroupItem, ReferenceViewerDialog, RepoIcon, RequestContext, RequestContextSchemaForm, RequestContextWrapper, Root, Row, RuleBuilder, RuleFieldSelect, RuleOperatorSelect, RuleRow, RuleValueInput, STORED_SCORER_TYPES, SchemaRequestContext, SchemaRequestContextProvider, ScoreDelta, ScoreDialog, ScorerCombobox, ScorerCreateContent, ScorerEditMain, ScorerEditSidebar, ScorerSelector, ScorerVersionCombobox, ScorersPage, ScorersSection, ScorersTable, ScoresList, ScoresTools, ScrollArea, ScrollBar, SearchField, SearchSkillsPanel, SearchWorkspacePanel, Searchbar, SearchbarWrapper, Section, SectionHeader$1 as SectionHeader, Sections, Select, SelectContent, SelectField$1 as SelectField, SelectGroup, SelectItem, SelectTrigger, SelectValue, SettingsIcon, ShadcnAutoFormFieldComponents, SideDialog, Skeleton, SkillDetail, SkillIcon, SkillRemoveButton, SkillUpdateButton, SkillsNotConfigured, SkillsTable, SlashIcon, Slider, SpanScoreList, SpanScoring, SpanTabs, Spinner, StudioConfigContext, StudioConfigForm, StudioConfigProvider, SubSectionHeader, Switch, Tab, TabContent, TabList, Table, Tabs, TargetSelector, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, TimePicker, ToolCoinIcon, ToolCombobox, ToolFallback, ToolIconMap, ToolInformation, ToolList$1 as ToolList, ToolPanel, ToolProviderDialog, ToolTable, ToolkitList, ToolsIcon, ToolsPage, ToolsSection, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TraceAsItemDialog, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineSpan, TraceTimelineTools, TracesList, TracesTools, TracingSettingsContext, TracingSettingsProvider, Truncate, TsIcon, Txt, TxtCell, VARIABLE_PATTERN, VariablesIcon, VariablesPage, WorkflowCoinIcon, WorkflowCombobox, WorkflowGraph, WorkflowIcon, WorkflowInformation, WorkflowLayout, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowStepDetailContext, WorkflowStepDetailProvider, WorkflowTable, WorkflowTrigger, WorkflowsPage, WorkflowsSection, WorkingMemoryContext, WorkingMemoryProvider, WorkspaceNotConfigured, agentFormSchema, arrayToRecord, buildObservationalMemoryForApi, buttonVariants, cleanProviderId, cn, collectMCPClientIds, columns$5 as columns, comboboxStyles, computeAgentInitialValues, convertWorkflowRunStateToStreamResult, countLeafRules, createDefaultRule, createDefaultRuleGroup, createField, createInstructionBlock, createVariableAutocomplete, exportItemsToCSV, exportItemsToJSON, extractPrompt, fieldConfig, fieldsToJSONSchema, findProviderById, flattenSchemaToVariables, formatHierarchicalSpans, getChildFieldOptions, getColumnTemplate, getFieldOptionAtPath, getFieldOptionsFromSchema, getItemListColumnTemplate, getMainContentContentClassName, getShortId, getSpanTypeUi, getStatusIcon, getToNextEntryFn, getToNextItemFn, getToPreviousEntryFn, getToPreviousItemFn, highlight, inputVariants, isActive, isRule, isRuleGroup, isWorkspaceV1Supported, joinModelId, jsonSchemaToFields, mapInstructionBlocksFromApi, mapInstructionBlocksToApi, mapScorersToApi, normalizeIntegrationToolsToRecord, normalizeScorersFromApi, normalizeToolsToRecord, parseError, parseFieldPath, parseJSONCell, parseObservationalMemoryFromApi, parseRow, parseSkillSource, providerMapToIcon, removeEmptyValues, resolveSerializedZodOutput, scorerFormSchema, scoresListColumns, spanTypePrefixes$1 as spanTypePrefixes, splitModelId, toast, traceScoresListColumns, tracesListColumns, transformIntegrationToolsForApi, useActivateAgentVersion, useActivateScorerVersion, useActivatedSkills, useAgent, useAgentCmsForm, useAgentCmsNavigation, useAgentEditForm, useAgentEditFormContext, useAgentInformationSettings, useAgentInformationTab, useAgentSettings, useAgentSkill, useAgentVersion, useAgentVersions, useAgents, useAllIntegrationTools, useAllModels, useCSVParser, useCloneThread, useCodemirrorTheme$1 as useCodemirrorTheme, useCompareAgentVersions, useCompareExperiments, useCompareScorerVersions, useCreateAgentVersion, useCreateScorerVersion, useCreateWorkspaceDirectory, useCurrentRun, useDataset, useDatasetExperiment, useDatasetExperimentResults, useDatasetExperiments, useDatasetItem, useDatasetItemVersion, useDatasetItemVersions, useDatasetItems, useDatasetMutations, useDatasetVersions, useDatasets, useDeleteAgentVersion, useDeleteScorerVersion, useDeleteThread, useDeleteWorkflowRun, useDeleteWorkspaceFile, useExecuteAgentTool, useExecuteMCPTool, useExecuteProcessor, useExecuteTool, useExperimentalFeatures, useFilteredModels, useFilteredProviders, useInView, useIndexWorkspaceContent, useInstallSkill, useIsCmsAvailable, useItemSelection, useJSONParser, useJSONSchemaForm, useJSONSchemaFormField, useJSONSchemaFormNestedContext, useLLMProviders, useLinkComponent, useMCPServerTool, useMCPServerTools, useMCPServerToolsById, useMCPServers, useMainSidebar, useMastraPackages, useMastraPlatform, useMaybeSidebar, useMemory, useMemoryConfig, useMemorySearch, useMemoryWithOMStatus, useMergedRequestContext, useNavigationCommand, useObservationalMemory, useObservationalMemoryContext, usePackageUpdates, usePlaygroundStore, usePopularSkillsSh, useProcessor, useProcessors, useProviderTools, useRemoveSkill, useReorderModelList, useRequestContextPresets, useResetAgentModel, useRestoreAgentVersion, useRestoreScorerVersion, useSchemaRequestContext, useScorer, useScorerEditForm, useScorerVersion, useScorerVersions, useScorers, useScoresByExperimentId, useScoresByScorerId, useSearchSkillsSh, useSearchWorkspace, useSearchWorkspaceSkills, useSkillPreview, useSpeechRecognition, useStoredAgent, useStoredAgentMutations, useStoredAgents, useStoredScorer, useStoredScorerMutations, useStudioConfig, useTableKeyboardNavigation, useThreadInput, useThreads, useTool, useToolProviders, useToolkits, useTools, useTraceSpanScores, useTracingSettings, useTryConnectMcp, useUpdateAgentModel, useUpdateModelInModelList, useUpdateSkills, useWorkflow, useWorkflowRun, useWorkflowRuns, useWorkflowStepDetail, useWorkflows, useWorkingMemory, useWorkspaceFile, useWorkspaceFileStat, useWorkspaceFiles, useWorkspaceInfo, useWorkspaceSkill, useWorkspaceSkillReference, useWorkspaceSkillReferences, useWorkspaceSkills, useWorkspaces, useWriteWorkspaceFile, useWriteWorkspaceFileFromFile, validateCsvRows, validateJSONData, validateMappedData, variableHighlight };
41899
+ export { AGENT_CMS_SECTIONS, ActionsMenu, ActivatedSkillsProvider, AddField, AddItemDialog, AddItemsToDatasetDialog, AddSkillDialog, AgentCMSBlock, AgentCMSBlocks, AgentChat, AgentCmsBottomBar, AgentCmsFormShell, AgentCmsSidebar, AgentCoinIcon, AgentCombobox, AgentEditFormProvider, AgentEditLayout, AgentEntityHeader, AgentIcon, AgentInformation, AgentInformationLayout, AgentInformationTabLayout, AgentLayout, AgentMemory, AgentMetadata, AgentMetadataCombinedProcessorList, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataSkillList, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWorkspaceToolsList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentSourceIcon, AgentToolPanel, AgentVersionCombobox, AgentVersionPanel, AgentsCmsLayout, AgentsPage, AgentsSection, AgentsTable, AiIcon, Alert, AlertDescription, AlertDialog, AlertTitle, ApiIcon, AutoForm, Avatar, Badge, BranchIcon, Breadcrumb$1 as Breadcrumb, Button, ButtonWithTooltip, ButtonsGroup, CSVImportDialog, Cell, ChatThreads, CheckIcon, Checkbox, ChevronIcon, CodeDiff, CodeEditor, Collapsible, CollapsibleContent, CollapsibleTrigger, Column, Columns, CombinedButtons, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CommitIcon, ComparisonView, ComposerModelSwitcher, ContentBlock, ContentBlocks, CopyButton, CreateDatasetDialog, CreateDatasetFromItemsDialog, CrossIcon, Crumb, DatasetCombobox, DatasetCompareVersionToolbar, DatasetCompareVersionsList, DatasetExperiments, DatasetItemContent, DatasetItemHeader, DatasetItemVersionsPanel, DatasetItemsList, DatasetPageContent, DatasetVersionsPanel, DatasetsTable, DatePicker, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeleteDatasetDialog, DeploymentIcon, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DisplayConditionsDialog, DividerIcon, DocsIcon, DuplicateDatasetDialog, DynamicForm, EditDatasetDialog, EditModeContent, ElementSelect, EmptyDatasetsTable, EmptyState$1 as EmptyState, Entity, EntityAccordionItem, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EntryList, EntryListSkeleton, EnvIcon, ExperimentPageHeader, ExperimentResultSpanPane, ExperimentResultTracePanel, ExperimentResultsListAndDetails, ExperimentStats, ExperimentTriggerDialog, Field, FieldDescription, FieldList, FieldName, FieldNullable, FieldOptional, FieldRemove, FieldType, FileBrowser, FileViewer, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InformationPage, Input, InputField, InstructionBlocksPage, IntegrationToolsSection, ItemList, ItemListSkeleton, ItemPageToolbar, JSONImportDialog, JSONSchemaForm, JudgeIcon, Kbd, KeyValueList, LLMModels, LLMProviders, Label, LatencyIcon, LinkComponentProvider, ListAndDetails, LogoWithoutText, LogsIcon, MCPClientCreateContent, MCPClientEditLayout, MCPClientFormSidebar, MCPClientList, MCPClientToolPreview, MCPDetail, MCPServerCombobox, MCPTable, MCPToolPanel, MainContentContent, MainContentLayout, MainHeader, MainSidebar, MainSidebarProvider, MarkdownRenderer, MastraPackagesInfo, MastraVersionFooter, McpCoinIcon, McpServerIcon, MemoryIcon, MemoryPage, MemorySearch, MemorySection, MultiCombobox, NavigationCommand, NestedFields, Notice, Notification, OPERATORS, OPERATOR_LABELS, ObservationalMemoryProvider, OpenAIIcon, PageHeader, PlaygroundConfigGuard, PlaygroundQueryClient, Popover, PopoverContent, PopoverTrigger, ProcessStepList, ProcessStepListItem, ProcessStepProgressBar, ProcessorCombobox, ProcessorIcon, ProcessorPanel, ProcessorTable, PromptIcon, ProviderLogo, RadioGroup, RadioGroupItem, ReferenceViewerDialog, RepoIcon, RequestContext, RequestContextSchemaForm, RequestContextWrapper, Root, Row, RuleBuilder, RuleFieldSelect, RuleOperatorSelect, RuleRow, RuleValueInput, STORED_SCORER_TYPES, SchemaRequestContext, SchemaRequestContextProvider, ScoreDelta, ScoreDialog, ScorerCombobox, ScorerCreateContent, ScorerEditMain, ScorerEditSidebar, ScorerSelector, ScorerVersionCombobox, ScorersPage, ScorersSection, ScorersTable, ScoresList, ScoresTools, ScrollArea, ScrollBar, SearchField, SearchSkillsPanel, SearchWorkspacePanel, Searchbar, SearchbarWrapper, Section, SectionHeader$1 as SectionHeader, Sections, Select, SelectContent, SelectField$1 as SelectField, SelectGroup, SelectItem, SelectTrigger, SelectValue, SettingsIcon, ShadcnAutoFormFieldComponents, SideDialog, Skeleton, SkillDetail, SkillIcon, SkillRemoveButton, SkillUpdateButton, SkillsNotConfigured, SkillsPage, SkillsTable, SlashIcon, Slider, SpanScoreList, SpanScoring, SpanTabs, Spinner, StudioConfigContext, StudioConfigForm, StudioConfigProvider, SubSectionHeader, Switch, Tab, TabContent, TabList, Table, Tabs, TargetSelector, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, TimePicker, ToolCoinIcon, ToolCombobox, ToolFallback, ToolIconMap, ToolInformation, ToolList$1 as ToolList, ToolPanel, ToolProviderDialog, ToolTable, ToolkitList, ToolsIcon, ToolsPage, ToolsSection, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TraceAsItemDialog, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineSpan, TraceTimelineTools, TracesList, TracesTools, TracingSettingsContext, TracingSettingsProvider, Tree, Truncate, TsIcon, Txt, TxtCell, VARIABLE_PATTERN, VariablesIcon, VariablesPage, WorkflowCoinIcon, WorkflowCombobox, WorkflowGraph, WorkflowIcon, WorkflowInformation, WorkflowLayout, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowStepDetailContext, WorkflowStepDetailProvider, WorkflowTable, WorkflowTrigger, WorkflowsPage, WorkflowsSection, WorkingMemoryContext, WorkingMemoryProvider, WorkspaceNotConfigured, agentFormSchema, arrayToRecord, buildObservationalMemoryForApi, buttonVariants, cleanProviderId, cn, collectMCPClientIds, columns$5 as columns, comboboxStyles, computeAgentInitialValues, convertWorkflowRunStateToStreamResult, countLeafRules, createDefaultRule, createDefaultRuleGroup, createField, createInstructionBlock, createVariableAutocomplete, exportItemsToCSV, exportItemsToJSON, extractPrompt, fieldConfig, fieldsToJSONSchema, findProviderById, flattenSchemaToVariables, formatHierarchicalSpans, getChildFieldOptions, getColumnTemplate, getFieldOptionAtPath, getFieldOptionsFromSchema, getItemListColumnTemplate, getMainContentContentClassName, getShortId, getSpanTypeUi, getStatusIcon, getToNextEntryFn, getToNextItemFn, getToPreviousEntryFn, getToPreviousItemFn, highlight, inputVariants, isActive, isRule, isRuleGroup, isWorkspaceV1Supported, joinModelId, jsonSchemaToFields, mapInstructionBlocksFromApi, mapInstructionBlocksToApi, mapScorersToApi, normalizeIntegrationToolsToRecord, normalizeScorersFromApi, normalizeSkillsFromApi, normalizeToolsToRecord, normalizeWorkspaceFromApi, parseError, parseFieldPath, parseJSONCell, parseObservationalMemoryFromApi, parseRow, parseSkillSource, providerMapToIcon, removeEmptyValues, resolveSerializedZodOutput, scorerFormSchema, scoresListColumns, spanTypePrefixes$1 as spanTypePrefixes, splitModelId, toast, traceScoresListColumns, tracesListColumns, transformIntegrationToolsForApi, useActivateAgentVersion, useActivateScorerVersion, useActivatedSkills, useAgent, useAgentCmsForm, useAgentCmsNavigation, useAgentEditForm, useAgentEditFormContext, useAgentInformationSettings, useAgentInformationTab, useAgentSettings, useAgentSkill, useAgentVersion, useAgentVersions, useAgents, useAllIntegrationTools, useAllModels, useCSVParser, useCloneThread, useCodemirrorTheme$1 as useCodemirrorTheme, useCompareAgentVersions, useCompareExperiments, useCompareScorerVersions, useCreateAgentVersion, useCreateScorerVersion, useCreateSkill, useCreateWorkspaceDirectory, useCurrentRun, useDataset, useDatasetExperiment, useDatasetExperimentResults, useDatasetExperiments, useDatasetItem, useDatasetItemVersion, useDatasetItemVersions, useDatasetItems, useDatasetMutations, useDatasetVersions, useDatasets, useDeleteAgentVersion, useDeleteScorerVersion, useDeleteThread, useDeleteWorkflowRun, useDeleteWorkspaceFile, useExecuteAgentTool, useExecuteMCPTool, useExecuteProcessor, useExecuteTool, useExperimentalFeatures, useFilteredModels, useFilteredProviders, useInView, useIndexWorkspaceContent, useInstallSkill, useIsCmsAvailable, useItemSelection, useJSONParser, useJSONSchemaForm, useJSONSchemaFormField, useJSONSchemaFormNestedContext, useLLMProviders, useLinkComponent, useMCPServerTool, useMCPServerTools, useMCPServerToolsById, useMCPServers, useMainSidebar, useMastraPackages, useMastraPlatform, useMaybeSidebar, useMemory, useMemoryConfig, useMemorySearch, useMemoryWithOMStatus, useMergedRequestContext, useNavigationCommand, useObservationalMemory, useObservationalMemoryContext, usePackageUpdates, usePlaygroundStore, usePopularSkillsSh, useProcessor, useProcessors, useProviderTools, useRemoveSkill, useReorderModelList, useRequestContextPresets, useResetAgentModel, useRestoreAgentVersion, useRestoreScorerVersion, useSchemaRequestContext, useScorer, useScorerEditForm, useScorerVersion, useScorerVersions, useScorers, useScoresByExperimentId, useScoresByScorerId, useSearchSkillsSh, useSearchWorkspace, useSearchWorkspaceSkills, useSkillPreview, useSpeechRecognition, useStoredAgent, useStoredAgentMutations, useStoredAgents, useStoredScorer, useStoredScorerMutations, useStoredSkills, useStudioConfig, useTableKeyboardNavigation, useThreadInput, useThreads, useTool, useToolProviders, useToolkits, useTools, useTraceSpanScores, useTracingSettings, useTryConnectMcp, useUpdateAgentModel, useUpdateModelInModelList, useUpdateSkills, useWorkflow, useWorkflowRun, useWorkflowRuns, useWorkflowStepDetail, useWorkflows, useWorkingMemory, useWorkspaceFile, useWorkspaceFileStat, useWorkspaceFiles, useWorkspaceInfo, useWorkspaceSkill, useWorkspaceSkillReference, useWorkspaceSkillReferences, useWorkspaceSkills, useWorkspaces, useWriteWorkspaceFile, useWriteWorkspaceFileFromFile, validateCsvRows, validateJSONData, validateMappedData, variableHighlight };
40420
41900
  //# sourceMappingURL=index.es.js.map