@mastra/playground-ui 6.7.1 → 6.7.2-alpha.1

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 (47) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/index.cjs.js +2758 -996
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +2754 -1004
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/src/components/ui/autoform/components/CustomArrayField.d.ts +6 -0
  7. package/dist/src/components/ui/autoform/components/CustomAutoFormField.d.ts +6 -0
  8. package/dist/src/components/ui/autoform/components/CustomObjectField.d.ts +6 -0
  9. package/dist/src/components/ui/autoform/components/DiscriminatedUnionField.d.ts +2 -0
  10. package/dist/src/components/ui/autoform/components/UnionField.d.ts +2 -0
  11. package/dist/src/components/ui/autoform/utils.d.ts +1 -0
  12. package/dist/src/components/ui/autoform/zodProvider/default-values.d.ts +3 -0
  13. package/dist/src/components/ui/autoform/zodProvider/index.d.ts +1 -0
  14. package/dist/src/components/ui/code-mirror-block.d.ts +2 -0
  15. package/dist/src/components/ui/copy-button.d.ts +4 -1
  16. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-link.d.ts +1 -0
  17. package/dist/src/domains/agents/components/AgentToolPanel.d.ts +5 -0
  18. package/dist/src/domains/agents/components/agent-information/agent-information.d.ts +5 -0
  19. package/dist/src/domains/agents/components/agent-information/agent-instructions-enhancer.d.ts +5 -0
  20. package/dist/src/domains/agents/components/agent-information/agent-memory-config.d.ts +5 -0
  21. package/dist/src/domains/agents/components/agent-information/agent-memory.d.ts +6 -0
  22. package/dist/src/domains/agents/components/agent-information/agent-working-memory.d.ts +5 -0
  23. package/dist/src/domains/agents/components/agent-information/code-display.d.ts +10 -0
  24. package/dist/src/domains/agents/components/agent-information/current-instructions.d.ts +15 -0
  25. package/dist/src/domains/agents/components/agent-information/version-actions.d.ts +8 -0
  26. package/dist/src/domains/agents/components/agent-information/version-history-dialog.d.ts +9 -0
  27. package/dist/src/domains/agents/components/agent-information/version-history.d.ts +10 -0
  28. package/dist/src/domains/agents/components/agent-information/version-item.d.ts +14 -0
  29. package/dist/src/domains/agents/hooks/use-prompt-enhancer.d.ts +19 -0
  30. package/dist/src/domains/agents/hooks/use-prompt-versions.d.ts +12 -0
  31. package/dist/src/domains/agents/index.d.ts +2 -0
  32. package/dist/src/domains/mcps/components/MCPDetail.d.ts +12 -0
  33. package/dist/src/domains/mcps/components/MCPToolPanel.d.ts +5 -0
  34. package/dist/src/domains/mcps/hooks/index.d.ts +3 -0
  35. package/dist/src/domains/mcps/hooks/use-mcp-server-tool.d.ts +2 -0
  36. package/dist/src/domains/mcps/hooks/use-mcp-servers.d.ts +1 -0
  37. package/dist/src/domains/mcps/index.d.ts +3 -1
  38. package/dist/src/domains/tools/components/ToolExecutor.d.ts +14 -0
  39. package/dist/src/domains/tools/components/ToolIcon.d.ts +5 -0
  40. package/dist/src/domains/tools/components/ToolInformation.d.ts +7 -0
  41. package/dist/src/domains/tools/components/ToolPanel.d.ts +4 -0
  42. package/dist/src/domains/tools/components/index.d.ts +4 -0
  43. package/dist/src/domains/tools/hooks/index.d.ts +1 -0
  44. package/dist/src/domains/tools/hooks/use-all-tools.d.ts +2 -0
  45. package/dist/src/domains/tools/index.d.ts +1 -0
  46. package/dist/src/lib/framework.d.ts +2 -1
  47. package/package.json +6 -6
package/dist/index.cjs.js CHANGED
@@ -15,7 +15,7 @@ const remarkGfm = require('remark-gfm');
15
15
  const reactSyntaxHighlighter = require('@assistant-ui/react-syntax-highlighter');
16
16
  const prism = require('react-syntax-highlighter/dist/cjs/styles/prism');
17
17
  const langJson = require('@codemirror/lang-json');
18
- const highlight = require('@lezer/highlight');
18
+ const highlight$1 = require('@lezer/highlight');
19
19
  const codemirrorThemeDracula = require('@uiw/codemirror-theme-dracula');
20
20
  const CodeMirror = require('@uiw/react-codemirror');
21
21
  const sonner = require('sonner');
@@ -26,7 +26,6 @@ const Dagre = require('@dagrejs/dagre');
26
26
  const prismReactRenderer = require('prism-react-renderer');
27
27
  const CollapsiblePrimitive = require('@radix-ui/react-collapsible');
28
28
  const ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
29
- const colors = require('./colors-B_l6leHd.cjs');
30
29
  const prettier = require('prettier');
31
30
  const prettierPluginBabel = require('prettier/plugins/babel');
32
31
  const prettierPluginEstree = require('prettier/plugins/estree');
@@ -45,14 +44,18 @@ const reactDayPicker = require('react-day-picker');
45
44
  const PopoverPrimitive = require('@radix-ui/react-popover');
46
45
  const SelectPrimitive = require('@radix-ui/react-select');
47
46
  const uuid = require('@lukeed/uuid');
47
+ const reactHookForm = require('react-hook-form');
48
+ const core = require('@autoform/core');
48
49
  const LabelPrimitive = require('@radix-ui/react-label');
49
50
  const v4 = require('@autoform/zod/v4');
50
51
  const v3 = require('zod/v3');
52
+ const z$1 = require('zod/v4');
51
53
  const RadioGroupPrimitive = require('@radix-ui/react-radio-group');
52
54
  const react$3 = require('@mastra/react');
53
55
  const reactQuery = require('@tanstack/react-query');
54
56
  const reactTable = require('@tanstack/react-table');
55
57
  const runtimeContext = require('@mastra/core/runtime-context');
58
+ const colors = require('./colors-B_l6leHd.cjs');
56
59
  const Markdown = require('react-markdown');
57
60
  const shallow = require('zustand/shallow');
58
61
  const di = require('@mastra/core/di');
@@ -4347,25 +4350,20 @@ function useCopyToClipboard({ text, copyMessage = "Copied to clipboard!" }) {
4347
4350
  return { isCopied, handleCopy };
4348
4351
  }
4349
4352
 
4350
- function CopyButton({ content, copyMessage, className }) {
4351
- const { isCopied, handleCopy } = useCopyToClipboard({
4353
+ function CopyButton({
4354
+ content,
4355
+ copyMessage,
4356
+ tooltip = "Copy to clipboard",
4357
+ iconSize = "default"
4358
+ }) {
4359
+ const { handleCopy } = useCopyToClipboard({
4352
4360
  text: content,
4353
4361
  copyMessage
4354
4362
  });
4355
- return /* @__PURE__ */ jsxRuntime.jsxs(
4356
- Button$2,
4357
- {
4358
- variant: "ghost",
4359
- size: "icon",
4360
- className: cn("relative h-6 w-6", className),
4361
- "aria-label": "Copy to clipboard",
4362
- onClick: handleCopy,
4363
- children: [
4364
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-4 w-4 transition-transform ease-in-out", isCopied ? "scale-100" : "scale-0") }) }),
4365
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: cn("h-4 w-4 transition-transform ease-in-out", isCopied ? "scale-0" : "scale-100") })
4366
- ]
4367
- }
4368
- );
4363
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
4364
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleCopy, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "transition-colors hover:bg-surface4 rounded-lg text-icon3 hover:text-icon6", size: iconSize, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, {}) }) }) }),
4365
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: tooltip })
4366
+ ] });
4369
4367
  }
4370
4368
 
4371
4369
  const useCodemirrorTheme$2 = () => {
@@ -4379,7 +4377,7 @@ const useCodemirrorTheme$2 = () => {
4379
4377
  background: "transparent",
4380
4378
  gutterForeground: "#939393"
4381
4379
  },
4382
- styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
4380
+ styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
4383
4381
  }),
4384
4382
  []
4385
4383
  );
@@ -4396,6 +4394,19 @@ const SyntaxHighlighter$2 = ({
4396
4394
  /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: formattedCode, theme, extensions: [langJson.jsonLanguage] })
4397
4395
  ] });
4398
4396
  };
4397
+ async function highlight(code, language) {
4398
+ const { codeToTokens, bundledLanguages } = await import('shiki');
4399
+ if (!(language in bundledLanguages)) return null;
4400
+ const { tokens } = await codeToTokens(code, {
4401
+ lang: language,
4402
+ defaultColor: false,
4403
+ themes: {
4404
+ light: "github-light",
4405
+ dark: "github-dark"
4406
+ }
4407
+ });
4408
+ return tokens;
4409
+ }
4399
4410
 
4400
4411
  const variantClasses$2 = {
4401
4412
  default: "text-icon3",
@@ -5288,10 +5299,10 @@ const useCodemirrorTheme$1 = () => {
5288
5299
  fontSize: "0.8rem",
5289
5300
  lineHighlight: "transparent",
5290
5301
  gutterBackground: "transparent",
5291
- gutterForeground: colors.IconColors.icon3,
5302
+ gutterForeground: "#939393",
5292
5303
  background: "transparent"
5293
5304
  },
5294
- styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
5305
+ styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
5295
5306
  }),
5296
5307
  []
5297
5308
  );
@@ -6869,6 +6880,145 @@ const RecordField = ({ inputProps, field, error, id }) => {
6869
6880
  ] });
6870
6881
  };
6871
6882
 
6883
+ const CustomObjectField = ({ field, path }) => {
6884
+ const { uiComponents } = react$2.useAutoForm();
6885
+ return /* @__PURE__ */ jsxRuntime.jsx(uiComponents.ObjectWrapper, { label: core.getLabel(field), field, children: Object.entries(field.schema).map(([_key, subField]) => /* @__PURE__ */ jsxRuntime.jsx(
6886
+ CustomAutoFormField,
6887
+ {
6888
+ field: subField,
6889
+ path: [...path, subField.key]
6890
+ },
6891
+ `${path.join(".")}.${subField.key}`
6892
+ )) });
6893
+ };
6894
+
6895
+ const CustomArrayField = ({ field, path }) => {
6896
+ const { uiComponents } = react$2.useAutoForm();
6897
+ const { control } = reactHookForm.useFormContext();
6898
+ const { fields, append, remove } = reactHookForm.useFieldArray({
6899
+ control,
6900
+ name: path.join(".")
6901
+ });
6902
+ const subFieldType = field.schema?.[0]?.type;
6903
+ let defaultValue;
6904
+ if (subFieldType === "object") {
6905
+ defaultValue = {};
6906
+ } else if (subFieldType === "array") {
6907
+ defaultValue = [];
6908
+ } else {
6909
+ defaultValue = null;
6910
+ }
6911
+ return /* @__PURE__ */ jsxRuntime.jsx(uiComponents.ArrayWrapper, { label: core.getLabel(field), field, onAddItem: () => append(defaultValue), children: fields.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(uiComponents.ArrayElementWrapper, { onRemove: () => remove(index), index, children: /* @__PURE__ */ jsxRuntime.jsx(CustomAutoFormField, { field: field.schema[0], path: [...path, index.toString()] }) }, item.id)) });
6912
+ };
6913
+
6914
+ const CustomAutoFormField = ({ field, path }) => {
6915
+ const { formComponents, uiComponents } = react$2.useAutoForm();
6916
+ const {
6917
+ register,
6918
+ formState: { errors },
6919
+ getValues
6920
+ } = reactHookForm.useFormContext();
6921
+ const fullPath = path.join(".");
6922
+ const error = react$2.getPathInObject(errors, path)?.message;
6923
+ const value = getValues(fullPath);
6924
+ const FieldWrapper = field.fieldConfig?.fieldWrapper || uiComponents.FieldWrapper;
6925
+ let FieldComponent = () => /* @__PURE__ */ jsxRuntime.jsx(
6926
+ uiComponents.ErrorMessage,
6927
+ {
6928
+ error: `[AutoForm Configuration Error] No component found for type "${field.type}" nor a fallback`
6929
+ }
6930
+ );
6931
+ if (field.type === "array") {
6932
+ FieldComponent = CustomArrayField;
6933
+ } else if (field.type === "object") {
6934
+ FieldComponent = CustomObjectField;
6935
+ } else if (field.type in formComponents) {
6936
+ FieldComponent = formComponents[field.type];
6937
+ } else if ("fallback" in formComponents) {
6938
+ FieldComponent = formComponents.fallback;
6939
+ }
6940
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldWrapper, { label: core.getLabel(field), error, id: fullPath, field, children: /* @__PURE__ */ jsxRuntime.jsx(
6941
+ FieldComponent,
6942
+ {
6943
+ label: core.getLabel(field),
6944
+ field,
6945
+ value,
6946
+ error,
6947
+ id: fullPath,
6948
+ path,
6949
+ inputProps: {
6950
+ required: field.required,
6951
+ error,
6952
+ key: `${fullPath}-input`,
6953
+ ...field.fieldConfig?.inputProps,
6954
+ ...register(fullPath)
6955
+ }
6956
+ },
6957
+ fullPath
6958
+ ) });
6959
+ };
6960
+
6961
+ const UnionField = ({ field, inputProps }) => {
6962
+ const path = inputProps.name?.split(".") ?? [];
6963
+ return field.schema?.map((schema, index) => {
6964
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6965
+ /* @__PURE__ */ jsxRuntime.jsx(CustomAutoFormField, { field: schema, path }, path.join(".")),
6966
+ index < (field.schema?.length ?? 0) - 1 && /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-center", children: "OR" })
6967
+ ] }, schema.key);
6968
+ });
6969
+ };
6970
+
6971
+ const DiscriminatedUnionField = ({ field, path }) => {
6972
+ const { watch } = reactHookForm.useFormContext();
6973
+ const fullPath = path.join(".");
6974
+ const value = watch(fullPath);
6975
+ const allSchemas = field.schema?.flatMap((schema) => schema.schema || []) || [];
6976
+ const literalSchemas = allSchemas?.filter((schema) => schema.fieldConfig?.customData?.isLiteral) || [];
6977
+ const firstLiteralSchema = literalSchemas[0];
6978
+ const literalSchemaField = literalSchemas?.reduce(
6979
+ (acc, schema) => {
6980
+ const optionValues = (schema.fieldConfig?.customData?.literalValues ?? []).map(
6981
+ (value2) => [value2, value2]
6982
+ );
6983
+ acc.options?.push(...optionValues);
6984
+ return acc;
6985
+ },
6986
+ {
6987
+ key: firstLiteralSchema.key,
6988
+ required: firstLiteralSchema.required,
6989
+ type: "select",
6990
+ default: firstLiteralSchema.default,
6991
+ description: firstLiteralSchema.description,
6992
+ options: [],
6993
+ fieldConfig: firstLiteralSchema.fieldConfig
6994
+ }
6995
+ );
6996
+ const otherFieldSchemas = field.schema?.reduce(
6997
+ (acc, schema) => {
6998
+ const literalSchema = schema.schema?.find((schema2) => schema2.fieldConfig?.customData?.isLiteral);
6999
+ const literalSchemaValue = literalSchema?.fieldConfig?.customData?.literalValues?.[0];
7000
+ const otherSchemas = schema.schema?.filter((schema2) => schema2.key !== literalSchema?.key) ?? [];
7001
+ if (literalSchemaValue) {
7002
+ acc[literalSchemaValue] = otherSchemas;
7003
+ }
7004
+ return acc;
7005
+ },
7006
+ {}
7007
+ );
7008
+ const literalFieldValue = value?.[literalSchemaField.key];
7009
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7010
+ /* @__PURE__ */ jsxRuntime.jsx(
7011
+ CustomAutoFormField,
7012
+ {
7013
+ field: literalSchemaField,
7014
+ path: [...path, literalSchemaField.key]
7015
+ },
7016
+ `${fullPath}.${literalSchemaField.key}`
7017
+ ),
7018
+ literalFieldValue && otherFieldSchemas?.[literalFieldValue] && otherFieldSchemas[literalFieldValue].map((schema) => /* @__PURE__ */ jsxRuntime.jsx(CustomAutoFormField, { field: schema, path: [...path, schema.key] }, `${fullPath}.${schema.key}`))
7019
+ ] }, field.key);
7020
+ };
7021
+
6872
7022
  const ShadcnUIComponents = {
6873
7023
  Form,
6874
7024
  FieldWrapper,
@@ -6896,6 +7046,8 @@ function AutoForm({
6896
7046
  date: (props2) => /* @__PURE__ */ jsxRuntime.jsx(DateField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
6897
7047
  select: (props2) => /* @__PURE__ */ jsxRuntime.jsx(SelectField$1, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
6898
7048
  record: (props2) => /* @__PURE__ */ jsxRuntime.jsx(RecordField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
7049
+ union: (props2) => /* @__PURE__ */ jsxRuntime.jsx(UnionField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
7050
+ "discriminated-union": (props2) => /* @__PURE__ */ jsxRuntime.jsx(DiscriminatedUnionField, { ...props2, inputProps: { ...props2.inputProps, readOnly } }),
6899
7051
  ...formComponents
6900
7052
  }
6901
7053
  }
@@ -6903,6 +7055,39 @@ function AutoForm({
6903
7055
  }
6904
7056
 
6905
7057
  react$2.buildZodFieldConfig();
7058
+ function removeEmptyValues(values) {
7059
+ const result = {};
7060
+ for (const key in values) {
7061
+ const value = values[key];
7062
+ if ([null, void 0, "", [], {}].includes(value)) {
7063
+ continue;
7064
+ }
7065
+ if (Array.isArray(value)) {
7066
+ const newArray = value.map((item) => {
7067
+ if (typeof item === "object") {
7068
+ const cleanedItem = removeEmptyValues(item);
7069
+ if (Object.keys(cleanedItem).length > 0) {
7070
+ return cleanedItem;
7071
+ }
7072
+ return null;
7073
+ }
7074
+ return item;
7075
+ });
7076
+ const filteredArray = newArray.filter((item) => item !== null);
7077
+ if (filteredArray.length > 0) {
7078
+ result[key] = filteredArray;
7079
+ }
7080
+ } else if (typeof value === "object") {
7081
+ const cleanedValue = removeEmptyValues(value);
7082
+ if (Object.keys(cleanedValue).length > 0) {
7083
+ result[key] = cleanedValue;
7084
+ }
7085
+ } else {
7086
+ result[key] = value;
7087
+ }
7088
+ }
7089
+ return result;
7090
+ }
6906
7091
 
6907
7092
  const labelVariants = cva("text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
6908
7093
  const Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(LabelPrimitive__namespace.Root, { ref, className: clsx(labelVariants(), className), ...props }));
@@ -6929,14 +7114,55 @@ function inferFieldType(schema, fieldConfig) {
6929
7114
  if (schema instanceof v3.z.ZodNativeEnum) return "select";
6930
7115
  if (schema instanceof z.z.ZodArray) return "array";
6931
7116
  if (schema instanceof z.z.ZodRecord) return "record";
7117
+ if (schema instanceof z.z.ZodUnion) {
7118
+ const options = schema._zod.def.options;
7119
+ const hasLiteral = options.every((option) => {
7120
+ if ("shape" in option._zod.def) {
7121
+ return Object.values(option._zod.def.shape).some(
7122
+ (value) => value instanceof z.z.ZodLiteral
7123
+ );
7124
+ }
7125
+ return false;
7126
+ });
7127
+ if (hasLiteral) {
7128
+ return "discriminated-union";
7129
+ }
7130
+ return "union";
7131
+ }
6932
7132
  return "string";
6933
7133
  }
6934
7134
 
7135
+ function getDefaultValueInZodStack(schema) {
7136
+ if (schema instanceof z$1.core.$ZodDefault) {
7137
+ return schema._zod.def.defaultValue;
7138
+ } else if ("innerType" in schema._zod.def) {
7139
+ return getDefaultValueInZodStack(schema._zod.def.innerType);
7140
+ } else if ("shape" in schema._zod.def) {
7141
+ return getDefaultValues(schema);
7142
+ } else if ("left" in schema._zod.def && "right" in schema._zod.def) {
7143
+ const left = getDefaultValues(schema._zod.def.left);
7144
+ const right = getDefaultValues(schema._zod.def.right);
7145
+ return { ...left, ...right };
7146
+ }
7147
+ return void 0;
7148
+ }
7149
+ function getDefaultValues(schema) {
7150
+ const shape = schema._zod.def.shape;
7151
+ const defaultValues = {};
7152
+ for (const [key, field] of Object.entries(shape)) {
7153
+ const defaultValue = getDefaultValueInZodStack(field);
7154
+ if (defaultValue !== void 0) {
7155
+ defaultValues[key] = defaultValue;
7156
+ }
7157
+ }
7158
+ return defaultValues;
7159
+ }
7160
+
6935
7161
  function parseField(key, schema) {
6936
7162
  const baseSchema = getBaseSchema(schema);
6937
7163
  const fieldConfig = v4.getFieldConfigInZodStack(schema);
6938
7164
  const type = inferFieldType(baseSchema, fieldConfig);
6939
- const defaultValue = v4.getDefaultValueInZodStack(schema);
7165
+ const defaultValue = getDefaultValueInZodStack(schema);
6940
7166
  const options = baseSchema._zod.def?.entries;
6941
7167
  let optionValues = [];
6942
7168
  if (options) {
@@ -6950,11 +7176,16 @@ function parseField(key, schema) {
6950
7176
  if (baseSchema instanceof v3.z.ZodObject || baseSchema instanceof z.z.ZodObject) {
6951
7177
  subSchema = Object.entries(baseSchema.shape).map(([key2, field]) => parseField(key2, field));
6952
7178
  }
7179
+ if (baseSchema instanceof v3.z.ZodUnion || baseSchema instanceof z.z.ZodUnion) {
7180
+ subSchema = Object.entries(baseSchema.def.options).map(([key2, field]) => {
7181
+ return parseField(key2, field);
7182
+ });
7183
+ }
6953
7184
  if (baseSchema instanceof v3.z.ZodIntersection || baseSchema instanceof z.z.ZodIntersection) {
6954
- const subSchemaLeft = Object.entries(baseSchema._def.left.shape).map(
7185
+ const subSchemaLeft = Object.entries(baseSchema.def.left.shape).map(
6955
7186
  ([key2, field]) => parseField(key2, field)
6956
7187
  );
6957
- const subSchemaRight = Object.entries(baseSchema._def.right.shape).map(
7188
+ const subSchemaRight = Object.entries(baseSchema.def.right.shape).map(
6958
7189
  ([key2, field]) => parseField(key2, field)
6959
7190
  );
6960
7191
  subSchema = [...subSchemaLeft, ...subSchemaRight];
@@ -6962,13 +7193,21 @@ function parseField(key, schema) {
6962
7193
  if (baseSchema instanceof v3.z.ZodArray || baseSchema instanceof z.z.ZodArray) {
6963
7194
  subSchema = [parseField("0", baseSchema._zod.def.element)];
6964
7195
  }
7196
+ const isLiteral = baseSchema instanceof z.z.ZodLiteral;
7197
+ const literalValues = isLiteral ? baseSchema._zod.def.values : void 0;
6965
7198
  return {
6966
7199
  key,
6967
7200
  type,
6968
7201
  required: !schema.optional(),
6969
7202
  default: defaultValue,
6970
7203
  description: baseSchema.description,
6971
- fieldConfig,
7204
+ fieldConfig: isLiteral || Object.keys(fieldConfig ?? {})?.length > 0 ? {
7205
+ ...fieldConfig,
7206
+ customData: {
7207
+ ...fieldConfig?.customData ?? {},
7208
+ ...isLiteral ? { isLiteral, literalValues } : {}
7209
+ }
7210
+ } : void 0,
6972
7211
  options: optionValues,
6973
7212
  schema: subSchema
6974
7213
  };
@@ -6993,8 +7232,12 @@ class CustomZodProvider extends v4.ZodProvider {
6993
7232
  super(schema);
6994
7233
  this._schema = schema;
6995
7234
  }
7235
+ getDefaultValues() {
7236
+ return getDefaultValues(this._schema);
7237
+ }
6996
7238
  validateSchema(values) {
6997
- const result = super.validateSchema(values);
7239
+ const cleanedValues = removeEmptyValues(values);
7240
+ const result = super.validateSchema(cleanedValues);
6998
7241
  return result;
6999
7242
  }
7000
7243
  parseSchema() {
@@ -7703,6 +7946,7 @@ const LinkComponentContext = React.createContext({
7703
7946
  scorerLink: () => "",
7704
7947
  toolLink: () => "",
7705
7948
  mcpServerLink: () => "",
7949
+ mcpServerToolLink: () => "",
7706
7950
  workflowRunLink: () => ""
7707
7951
  }
7708
7952
  });
@@ -12561,7 +12805,7 @@ const useCodemirrorTheme = () => {
12561
12805
  gutterForeground: "#939393",
12562
12806
  background: "transparent"
12563
12807
  },
12564
- styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
12808
+ styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
12565
12809
  }),
12566
12810
  []
12567
12811
  );
@@ -13234,7 +13478,7 @@ function MainSidebarNavLink({
13234
13478
  className
13235
13479
  }) {
13236
13480
  const { Link } = useLinkComponent();
13237
- const isDefaultState = state === "default";
13481
+ const isCollapsed = state === "collapsed";
13238
13482
  const isFeatured = link?.variant === "featured";
13239
13483
  const linkParams = link?.url?.startsWith("http") ? { target: "_blank", rel: "noreferrer" } : {};
13240
13484
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -13248,22 +13492,31 @@ function MainSidebarNavLink({
13248
13492
  {
13249
13493
  "[&>a]:text-icon5 [&>a]:bg-surface3": isActive,
13250
13494
  "[&_svg]:text-icon5": isActive,
13251
- "[&>a]:justify-start ": isDefaultState,
13252
- "[&_svg]:text-icon3": !isDefaultState,
13495
+ "[&>a]:justify-start ": !isCollapsed,
13496
+ "[&_svg]:text-icon3": isCollapsed,
13253
13497
  "[&>a]:rounded-md [&>a]:my-[0.5rem] [&>a]:bg-accent1/75 [&>a:hover]:bg-accent1/85 [&>a]:text-black [&>a:hover]:text-black": isFeatured,
13254
- "[&_svg]:text-black/75": isFeatured
13498
+ "[&_svg]:text-black/75 [&>a:hover_svg]:text-black": isFeatured
13255
13499
  },
13256
13500
  className
13257
13501
  ),
13258
- children: link ? /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: link.url, ...linkParams, children: [
13259
- isDefaultState ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: link.icon && link.icon }) : /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
13260
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: link.icon && link.icon }),
13261
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "right", align: "center", className: "bg-border1 text-icon6 ml-[1rem]", children: link.name })
13262
- ] }),
13263
- isDefaultState ? link.name : /* @__PURE__ */ jsxRuntime.jsx(VisuallyHidden.VisuallyHidden, { children: link.name }),
13502
+ children: link ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isCollapsed || link.tooltipMsg ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
13503
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: link.url, ...linkParams, children: [
13504
+ link.icon && link.icon,
13505
+ isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(VisuallyHidden.VisuallyHidden, { children: link.name }) : link.name,
13506
+ " ",
13507
+ children
13508
+ ] }) }),
13509
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "right", align: "center", className: "bg-border1 text-icon6 ml-[1rem]", children: link.tooltipMsg ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13510
+ isCollapsed && `${link.name} | `,
13511
+ " ",
13512
+ link.tooltipMsg
13513
+ ] }) : link.name })
13514
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: link.url, ...linkParams, children: [
13515
+ link.icon && link.icon,
13516
+ isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(VisuallyHidden.VisuallyHidden, { children: link.name }) : link.name,
13264
13517
  " ",
13265
13518
  children
13266
- ] }) : children
13519
+ ] }) }) : children
13267
13520
  }
13268
13521
  );
13269
13522
  }
@@ -14879,495 +15132,2127 @@ const useExecuteAgentTool = () => {
14879
15132
  });
14880
15133
  };
14881
15134
 
14882
- const NameCell$1 = ({ row }) => {
14883
- const { Link, paths } = useLinkComponent();
14884
- const tool = row.original;
15135
+ const ToolIconMap = {
15136
+ agent: AgentIcon,
15137
+ workflow: WorkflowIcon,
15138
+ tool: ToolsIcon
15139
+ };
15140
+
15141
+ const ToolInformation = ({ toolDescription, toolId, toolType }) => {
15142
+ const ToolIconComponent = ToolIconMap[toolType || "tool"];
15143
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-5 border-b-sm border-border1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-icon6 flex gap-2", children: [
15144
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: /* @__PURE__ */ jsxRuntime.jsx(ToolIconComponent, {}) }) }),
15145
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-4 justify-between w-full min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
15146
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", as: "h2", className: "font-medium truncate", children: toolId }),
15147
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: toolDescription })
15148
+ ] }) })
15149
+ ] }) });
15150
+ };
15151
+
15152
+ const ToolExecutor = ({
15153
+ isExecutingTool,
15154
+ zodInputSchema,
15155
+ handleExecuteTool,
15156
+ executionResult: result,
15157
+ errorString,
15158
+ toolDescription,
15159
+ toolId,
15160
+ toolType
15161
+ }) => {
15162
+ const theme = useCodemirrorTheme$1();
15163
+ const code = JSON.stringify(result ?? {}, null, 2);
15164
+ return /* @__PURE__ */ jsxRuntime.jsxs(MainContentContent, { hasLeftServiceColumn: true, className: "relative", children: [
15165
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface2 border-r-sm border-border1 w-[20rem]", children: [
15166
+ /* @__PURE__ */ jsxRuntime.jsx(ToolInformation, { toolDescription, toolId, toolType }),
15167
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-5 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
15168
+ DynamicForm,
15169
+ {
15170
+ isSubmitLoading: isExecutingTool,
15171
+ schema: zodInputSchema,
15172
+ onSubmit: (data) => {
15173
+ handleExecuteTool(data);
15174
+ },
15175
+ className: "h-auto pb-7"
15176
+ }
15177
+ ) })
15178
+ ] }),
15179
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: code, tooltip: "Copy JSON result to clipboard" }) }),
15180
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-5 h-full relative overflow-x-auto overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: errorString || code, editable: true, theme, extensions: [langJson.jsonLanguage] }) })
15181
+ ] });
15182
+ };
15183
+
15184
+ const AgentToolPanel = ({ toolId, agentId }) => {
15185
+ const { data: agent, isLoading: isAgentLoading } = useAgent(agentId);
15186
+ const tool = Object.values(agent?.tools ?? {}).find((tool2) => tool2.id === toolId);
15187
+ const { mutateAsync: executeTool, isPending: isExecutingTool, data: result } = useExecuteAgentTool();
15188
+ const { runtimeContext: playgroundRuntimeContext } = usePlaygroundStore();
15189
+ const handleExecuteTool = async (data) => {
15190
+ if (!tool) return;
15191
+ await executeTool({
15192
+ agentId,
15193
+ toolId: tool.id,
15194
+ input: data,
15195
+ playgroundRuntimeContext
15196
+ });
15197
+ };
15198
+ const zodInputSchema = tool?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(superjson.parse(tool?.inputSchema))) : z.z.object({});
15199
+ if (isAgentLoading) return null;
15200
+ if (!tool)
15201
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center px-6", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", className: "text-icon3", children: "Tool not found" }) });
14885
15202
  return /* @__PURE__ */ jsxRuntime.jsx(
14886
- EntryCell,
15203
+ ToolExecutor,
14887
15204
  {
14888
- name: /* @__PURE__ */ jsxRuntime.jsx(Link, { className: "w-full space-y-0", href: paths.toolLink(tool.id), children: tool.id }),
14889
- description: tool.description
15205
+ executionResult: result,
15206
+ isExecutingTool,
15207
+ zodInputSchema,
15208
+ handleExecuteTool,
15209
+ toolDescription: tool.description,
15210
+ toolId: tool.id
14890
15211
  }
14891
15212
  );
14892
15213
  };
14893
- const columns$1 = [
14894
- {
14895
- header: "Name",
14896
- accessorKey: "name",
14897
- cell: NameCell$1
14898
- },
14899
- {
14900
- header: "Attached entities",
14901
- accessorKey: "attachedEntities",
14902
- cell: ({ row }) => {
14903
- const tool = row.original;
14904
- const agentsCount = tool.agents.length;
14905
- return /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "default", icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, { className: "text-accent1" }), children: [
14906
- agentsCount,
14907
- " agent",
14908
- agentsCount > 1 ? "s" : ""
14909
- ] }) });
14910
- }
14911
- }
14912
- ];
14913
15214
 
14914
- const prepareToolsTable = (tools, agents) => {
14915
- const toolsWithAgents = /* @__PURE__ */ new Map();
14916
- const agentsKeys = Object.keys(agents);
14917
- for (const k of agentsKeys) {
14918
- const agent = agents[k];
14919
- const agentToolsDict = agent.tools;
14920
- const agentToolsKeys = Object.keys(agentToolsDict);
14921
- for (const key of agentToolsKeys) {
14922
- const tool = agentToolsDict[key];
14923
- if (!toolsWithAgents.has(tool.id)) {
14924
- toolsWithAgents.set(tool.id, {
14925
- ...tool,
14926
- agents: []
14927
- });
15215
+ const useMemory = (agentId) => {
15216
+ const client = react$3.useMastraClient();
15217
+ return reactQuery.useQuery({
15218
+ queryKey: ["memory", agentId],
15219
+ queryFn: () => agentId ? client.getMemoryStatus(agentId) : null,
15220
+ enabled: Boolean(agentId),
15221
+ staleTime: 5 * 60 * 1e3,
15222
+ // 5 minutes
15223
+ gcTime: 10 * 60 * 1e3,
15224
+ // 10 minutes
15225
+ retry: false
15226
+ });
15227
+ };
15228
+ const useMemoryConfig = (agentId) => {
15229
+ const client = react$3.useMastraClient();
15230
+ return reactQuery.useQuery({
15231
+ queryKey: ["memory", "config", agentId],
15232
+ queryFn: () => agentId ? client.getMemoryConfig({ agentId }) : null,
15233
+ enabled: Boolean(agentId),
15234
+ staleTime: 5 * 60 * 1e3,
15235
+ // 5 minutes
15236
+ gcTime: 10 * 60 * 1e3,
15237
+ // 10 minutes
15238
+ retry: false,
15239
+ refetchOnWindowFocus: false
15240
+ });
15241
+ };
15242
+ const useThreads = ({
15243
+ resourceId,
15244
+ agentId,
15245
+ isMemoryEnabled
15246
+ }) => {
15247
+ const client = react$3.useMastraClient();
15248
+ return reactQuery.useQuery({
15249
+ queryKey: ["memory", "threads", resourceId, agentId],
15250
+ queryFn: () => isMemoryEnabled ? client.getMemoryThreads({ resourceId, agentId }) : null,
15251
+ enabled: Boolean(isMemoryEnabled),
15252
+ staleTime: 0,
15253
+ gcTime: 0,
15254
+ retry: false,
15255
+ refetchOnWindowFocus: false
15256
+ });
15257
+ };
15258
+ const useDeleteThread = () => {
15259
+ const client = react$3.useMastraClient();
15260
+ const queryClient = reactQuery.useQueryClient();
15261
+ return reactQuery.useMutation({
15262
+ mutationFn: ({ threadId, agentId, networkId }) => client.deleteThread(threadId, { agentId, networkId }),
15263
+ onSuccess: (_, variables) => {
15264
+ const { agentId, networkId } = variables;
15265
+ if (agentId) {
15266
+ queryClient.invalidateQueries({ queryKey: ["memory", "threads", agentId, agentId] });
14928
15267
  }
14929
- toolsWithAgents.get(tool.id).agents.push({ ...agent, id: k });
14930
- }
14931
- }
14932
- for (const [_, tool] of Object.entries(tools)) {
14933
- if (!toolsWithAgents.has(tool.id)) {
14934
- toolsWithAgents.set(tool.id, {
14935
- ...tool,
14936
- agents: []
14937
- });
15268
+ if (networkId) {
15269
+ queryClient.invalidateQueries({ queryKey: ["network", "threads", networkId, networkId] });
15270
+ }
15271
+ sonner.toast.success("Chat deleted successfully");
15272
+ },
15273
+ onError: () => {
15274
+ sonner.toast.error("Failed to delete chat");
14938
15275
  }
14939
- }
14940
- return Array.from(toolsWithAgents.values());
14941
- };
14942
-
14943
- function ToolTable({ tools, agents, isLoading }) {
14944
- const [search, setSearch] = React.useState("");
14945
- const { navigate, paths } = useLinkComponent();
14946
- const toolData = React.useMemo(() => prepareToolsTable(tools, agents), [tools, agents]);
14947
- const table = reactTable.useReactTable({
14948
- data: toolData,
14949
- columns: columns$1,
14950
- getCoreRowModel: reactTable.getCoreRowModel()
14951
15276
  });
14952
- const ths = table.getHeaderGroups()[0];
14953
- const rows = table.getRowModel().rows.concat();
14954
- if (rows.length === 0 && !isLoading) {
14955
- return /* @__PURE__ */ jsxRuntime.jsx(EmptyToolsTable, {});
14956
- }
14957
- const filteredRows = rows.filter((row) => row.original.id.toLowerCase().includes(search.toLowerCase()));
14958
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
14959
- /* @__PURE__ */ jsxRuntime.jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Searchbar, { onSearch: setSearch, label: "Search tools", placeholder: "Search tools" }) }),
14960
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ToolTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
14961
- /* @__PURE__ */ jsxRuntime.jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: reactTable.flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
14962
- /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: filteredRows.map((row) => {
14963
- const firstAgent = row.original.agents[0];
14964
- const link = firstAgent ? paths.agentToolLink(firstAgent.id, row.original.id) : paths.toolLink(row.original.id);
14965
- return /* @__PURE__ */ jsxRuntime.jsx(Row, { onClick: () => navigate(link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id);
14966
- }) })
14967
- ] }) }) })
14968
- ] });
14969
- }
14970
- const ToolTableSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
14971
- /* @__PURE__ */ jsxRuntime.jsxs(Thead, { children: [
14972
- /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Name" }),
14973
- /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Used by" })
14974
- ] }),
14975
- /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs(Row, { children: [
14976
- /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) }),
14977
- /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) })
14978
- ] }, index)) })
14979
- ] });
14980
- const EmptyToolsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
14981
- EmptyState,
14982
- {
14983
- iconSlot: /* @__PURE__ */ jsxRuntime.jsx(ToolCoinIcon, {}),
14984
- titleSlot: "Configure Tools",
14985
- descriptionSlot: "Mastra tools are not configured yet. You can find more information in the documentation.",
14986
- actionSlot: /* @__PURE__ */ jsxRuntime.jsxs(
14987
- Button$1,
14988
- {
14989
- size: "lg",
14990
- className: "w-full",
14991
- variant: "light",
14992
- as: "a",
14993
- href: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
14994
- target: "_blank",
14995
- children: [
14996
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}) }),
14997
- "Docs"
14998
- ]
14999
- }
15000
- )
15001
- }
15002
- ) });
15003
-
15004
- const useExecuteTool = () => {
15005
- const client = react$3.useMastraClient();
15006
- return reactQuery.useMutation({
15007
- mutationFn: async ({
15008
- toolId,
15009
- input,
15010
- runtimeContext: playgroundRuntimeContext
15011
- }) => {
15012
- const runtimeContext = new di.RuntimeContext();
15013
- Object.entries(playgroundRuntimeContext ?? {}).forEach(([key, value]) => {
15014
- runtimeContext.set(key, value);
15015
- });
15016
- try {
15017
- const tool = client.getTool(toolId);
15018
- const response = await tool.execute({ data: input, runtimeContext });
15019
- return response;
15020
- } catch (error) {
15021
- sonner.toast.error("Error executing dev tool");
15022
- console.error("Error executing dev tool:", error);
15023
- throw error;
15277
+ };
15278
+ const useMemorySearch = ({
15279
+ agentId,
15280
+ resourceId,
15281
+ threadId
15282
+ }) => {
15283
+ const searchMemory = async (searchQuery, memoryConfig) => {
15284
+ if (!searchQuery.trim()) {
15285
+ return { results: [], count: 0, query: searchQuery };
15286
+ }
15287
+ const params = new URLSearchParams({
15288
+ searchQuery,
15289
+ resourceId,
15290
+ agentId
15291
+ });
15292
+ if (threadId) {
15293
+ params.append("threadId", threadId);
15294
+ }
15295
+ if (memoryConfig) {
15296
+ params.append("memoryConfig", JSON.stringify(memoryConfig));
15297
+ }
15298
+ const response = await fetch(`/api/memory/search?${params}`, {
15299
+ method: "GET",
15300
+ headers: {
15301
+ "Content-Type": "application/json",
15302
+ "x-mastra-dev-playground": "true"
15024
15303
  }
15304
+ });
15305
+ if (!response.ok) {
15306
+ const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
15307
+ console.error("Search memory error:", errorData);
15308
+ throw new Error(errorData.message || errorData.error || "Failed to search memory");
15025
15309
  }
15026
- });
15310
+ return response.json();
15311
+ };
15312
+ return { searchMemory };
15027
15313
  };
15028
15314
 
15029
- function TemplatesTools({
15030
- tagOptions,
15031
- selectedTag,
15032
- providerOptions,
15033
- selectedProvider,
15034
- onTagChange,
15035
- onProviderChange,
15036
- searchTerm,
15037
- onSearchChange,
15038
- onReset,
15039
- className,
15040
- isLoading
15041
- }) {
15042
- if (isLoading) {
15043
- return /* @__PURE__ */ jsxRuntime.jsxs(
15044
- "div",
15045
- {
15046
- className: cn(
15047
- "h-[6.5rem] flex items-center gap-[2rem]",
15048
- "[&>div]:bg-surface3 [&>div]:w-[12rem] [&>div]:h-[2rem] [&>div]:animate-pulse",
15049
- className
15050
- ),
15051
- children: [
15052
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
15053
- " ",
15054
- /* @__PURE__ */ jsxRuntime.jsx("div", {}),
15055
- " ",
15056
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
15057
- ]
15058
- }
15059
- );
15315
+ function MarkdownRenderer({ children }) {
15316
+ const processedText = children.replace(/\\n/g, "\n");
15317
+ return /* @__PURE__ */ jsxRuntime.jsx(Markdown, { remarkPlugins: [remarkGfm], components: COMPONENTS, className: "space-y-3", children: processedText });
15318
+ }
15319
+ const HighlightedPre = React.memo(({ children, language, ...props }) => {
15320
+ const [tokens, setTokens] = React.useState([]);
15321
+ React.useEffect(() => {
15322
+ highlight(children, language).then((tokens2) => {
15323
+ if (tokens2) setTokens(tokens2);
15324
+ });
15325
+ }, [children, language]);
15326
+ if (!tokens.length) {
15327
+ return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children });
15060
15328
  }
15061
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap mx-auto sticky top-0 gap-[2rem] bg-surface2 py-[2rem]", className), children: [
15062
- /* @__PURE__ */ jsxRuntime.jsx(
15063
- SearchField,
15064
- {
15065
- label: "Search templates",
15066
- value: searchTerm,
15067
- onChange: (e) => onSearchChange?.(e.target.value),
15068
- placeholder: "Search Template"
15069
- }
15070
- ),
15071
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Filter by tag", value: selectedTag, onValueChange: onTagChange, options: tagOptions }),
15329
+ return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: tokens.map((line, lineIndex) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15330
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: line.map((token, tokenIndex) => {
15331
+ const style = typeof token.htmlStyle === "string" ? void 0 : token.htmlStyle;
15332
+ return /* @__PURE__ */ jsxRuntime.jsx(
15333
+ "span",
15334
+ {
15335
+ className: "text-shiki-light bg-shiki-light-bg dark:text-shiki-dark dark:bg-shiki-dark-bg",
15336
+ style,
15337
+ children: token.content
15338
+ },
15339
+ tokenIndex
15340
+ );
15341
+ }) }, lineIndex),
15342
+ lineIndex !== tokens.length - 1 && "\n"
15343
+ ] })) }) });
15344
+ });
15345
+ HighlightedPre.displayName = "HighlightedCode";
15346
+ const CodeBlock = ({ children, className, language, ...restProps }) => {
15347
+ const code = typeof children === "string" ? children : childrenTakeAllStringContents(children);
15348
+ const preClass = cn(
15349
+ "overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]",
15350
+ className
15351
+ );
15352
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/code relative mb-4", children: [
15072
15353
  /* @__PURE__ */ jsxRuntime.jsx(
15073
- SelectField,
15354
+ React.Suspense,
15074
15355
  {
15075
- label: "Filter by provider",
15076
- value: selectedProvider,
15077
- onValueChange: onProviderChange,
15078
- options: providerOptions
15356
+ fallback: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: preClass, ...restProps, children }),
15357
+ children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedPre, { language, className: preClass, children: code })
15079
15358
  }
15080
15359
  ),
15081
- onReset && /* @__PURE__ */ jsxRuntime.jsxs(Button, { onClick: onReset, children: [
15082
- "Reset ",
15083
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {})
15084
- ] })
15360
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "invisible absolute right-2 top-2 flex space-x-1 rounded-lg p-1 opacity-0 transition-all duration-200 group-hover/code:visible group-hover/code:opacity-100", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: code, copyMessage: "Copied code to clipboard" }) })
15085
15361
  ] });
15362
+ };
15363
+ function childrenTakeAllStringContents(element) {
15364
+ if (typeof element === "string") {
15365
+ return element;
15366
+ }
15367
+ if (element?.props?.children) {
15368
+ let children = element.props.children;
15369
+ if (Array.isArray(children)) {
15370
+ return children.map((child) => childrenTakeAllStringContents(child)).join("");
15371
+ } else {
15372
+ return childrenTakeAllStringContents(children);
15373
+ }
15374
+ }
15375
+ return "";
15086
15376
  }
15087
-
15088
- function getRepoName(githubUrl) {
15089
- return githubUrl.replace(/\/$/, "").split("/").pop();
15090
- }
15091
- function Container({ children, className }) {
15092
- return /* @__PURE__ */ jsxRuntime.jsx(
15093
- "div",
15377
+ const COMPONENTS = {
15378
+ h1: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold", ...props, children }),
15379
+ h2: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-xl", ...props, children }),
15380
+ h3: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-lg", ...props, children }),
15381
+ h4: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-base", ...props, children }),
15382
+ h5: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "font-medium", ...props, children }),
15383
+ strong: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-semibold", ...props, children }),
15384
+ a: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("a", { className: "underline underline-offset-2", ...props, children }),
15385
+ blockquote: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 border-primary pl-4", ...props, children }),
15386
+ code: ({ children, className, ...rest }) => {
15387
+ const match = /language-(\w+)/.exec(className || "");
15388
+ return match ? /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { className, language: match[1], ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx(
15389
+ "code",
15390
+ {
15391
+ className: cn(
15392
+ "font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:bg-background/50 [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5"
15393
+ ),
15394
+ ...rest,
15395
+ children
15396
+ }
15397
+ );
15398
+ },
15399
+ pre: ({ children }) => children,
15400
+ ol: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal space-y-2 pl-6", ...props, children }),
15401
+ ul: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc space-y-2 pl-6", ...props, children }),
15402
+ li: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "my-1.5", ...props, children }),
15403
+ table: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse overflow-y-auto rounded-md border border-foreground/20", ...props, children }),
15404
+ th: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
15405
+ "th",
15094
15406
  {
15095
- className: cn(
15096
- "border border-border1 rounded-lg mt-[3rem] py-[2rem] lg:min-h-[25rem] transition-height px-[1rem] lg:px-[3rem]",
15097
- className
15098
- ),
15407
+ className: "border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right",
15408
+ ...props,
15099
15409
  children
15100
15410
  }
15101
- );
15411
+ ),
15412
+ td: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
15413
+ "td",
15414
+ {
15415
+ className: "border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right",
15416
+ ...props,
15417
+ children
15418
+ }
15419
+ ),
15420
+ tr: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "m-0 border-t p-0 even:bg-muted", ...props, children }),
15421
+ p: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap leading-relaxed", ...props, children }),
15422
+ hr: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-foreground/20", ...props })
15423
+ };
15424
+
15425
+ function CodeDisplay({
15426
+ content,
15427
+ height = "150px",
15428
+ isCopied = false,
15429
+ isDraft = false,
15430
+ onCopy,
15431
+ className = ""
15432
+ }) {
15433
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rounded-md border ${className}`, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 cursor-pointer hover:bg-mastra-bg-3/50 transition-colors group relative", onClick: onCopy, children: [
15434
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-[10px] whitespace-pre-wrap font-mono", children: content }),
15435
+ isDraft && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-yellow-500/20 text-yellow-500", children: "Draft - Save changes to apply" }) }),
15436
+ isCopied && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Copied!" }),
15437
+ onCopy && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-mastra-bg-3 text-mastra-el-4 opacity-0 group-hover:opacity-100 transition-opacity", children: "Click to copy" })
15438
+ ] }) }) });
15102
15439
  }
15103
15440
 
15104
- function TemplatesList({ templates, linkComponent, className, isLoading }) {
15105
- const LinkComponent = linkComponent || "a";
15441
+ const AgentWorkingMemory = ({ agentId }) => {
15442
+ const { threadExists, workingMemoryData, workingMemorySource, isLoading, isUpdating, updateWorkingMemory } = useWorkingMemory();
15443
+ const { data } = useMemoryConfig(agentId);
15444
+ const config = data?.config;
15445
+ const isWorkingMemoryEnabled = Boolean(config?.workingMemory?.enabled);
15446
+ const { isCopied, handleCopy } = useCopyToClipboard({
15447
+ text: workingMemoryData ?? "",
15448
+ copyMessage: "Working memory copied!"
15449
+ });
15450
+ const [editValue, setEditValue] = React.useState(workingMemoryData ?? "");
15451
+ const [isEditing, setIsEditing] = React.useState(false);
15452
+ React.useEffect(() => {
15453
+ setEditValue(workingMemoryData ?? "");
15454
+ }, [workingMemoryData]);
15106
15455
  if (isLoading) {
15107
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[4rem] bg-surface3 animate-pulse rounded-lg" }, index)) });
15456
+ return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-32 w-full" });
15108
15457
  }
15109
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: templates.map((template) => {
15110
- const hasMetaInfo = template?.agents || template?.tools || template?.networks || template?.workflows || template?.mcp;
15111
- return /* @__PURE__ */ jsxRuntime.jsxs(
15112
- "article",
15113
- {
15114
- className: cn(
15115
- "border border-border1 rounded-lg overflow-hidden w-full grid grid-cols-[1fr_auto] bg-surface3 transition-colors hover:bg-surface4"
15458
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
15459
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
15460
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
15461
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5", children: "Working Memory" }),
15462
+ isWorkingMemoryEnabled && workingMemorySource && /* @__PURE__ */ jsxRuntime.jsx(
15463
+ "span",
15464
+ {
15465
+ className: cn(
15466
+ "text-xs font-medium px-2 py-0.5 rounded",
15467
+ workingMemorySource === "resource" ? "bg-purple-500/20 text-purple-400" : "bg-blue-500/20 text-blue-400"
15468
+ ),
15469
+ title: workingMemorySource === "resource" ? "Shared across all threads for this agent" : "Specific to this conversation thread",
15470
+ children: workingMemorySource
15471
+ }
15472
+ )
15473
+ ] }),
15474
+ isWorkingMemoryEnabled && !threadExists && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-icon3", children: "Send a message to the agent to enable working memory." })
15475
+ ] }),
15476
+ isWorkingMemoryEnabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15477
+ !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: workingMemoryData ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: workingMemoryData.trim().startsWith("{") ? /* @__PURE__ */ jsxRuntime.jsx(
15478
+ CodeDisplay,
15479
+ {
15480
+ content: workingMemoryData || "",
15481
+ isCopied,
15482
+ onCopy: handleCopy,
15483
+ className: "bg-surface3 text-sm font-mono min-h-[150px] border border-border1 rounded-lg"
15484
+ }
15485
+ ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface3 border border-border1 rounded-lg", style: { height: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
15486
+ "div",
15487
+ {
15488
+ className: "p-3 cursor-pointer hover:bg-surface4/20 transition-colors relative group text-[10px]",
15489
+ onClick: handleCopy,
15490
+ children: [
15491
+ /* @__PURE__ */ jsxRuntime.jsx(MarkdownRenderer, { children: workingMemoryData }),
15492
+ isCopied && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Copied!" }),
15493
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-surface3 text-icon4 opacity-0 group-hover:opacity-100 transition-opacity", children: "Click to copy" })
15494
+ ]
15495
+ }
15496
+ ) }) }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-icon3 font-mono", children: 'No working memory content yet. Click "Edit Working Memory" to add content.' }) }) : /* @__PURE__ */ jsxRuntime.jsx(
15497
+ "textarea",
15498
+ {
15499
+ className: "w-full min-h-[150px] p-3 border border-border1 rounded-lg bg-surface3 font-mono text-sm text-icon5 resize-none",
15500
+ value: editValue,
15501
+ onChange: (e) => setEditValue(e.target.value),
15502
+ disabled: isUpdating,
15503
+ placeholder: "Enter working memory content..."
15504
+ }
15505
+ ),
15506
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
15507
+ Button$2,
15508
+ {
15509
+ variant: "secondary",
15510
+ size: "sm",
15511
+ onClick: () => setIsEditing(true),
15512
+ disabled: !threadExists || isUpdating,
15513
+ className: "text-xs",
15514
+ children: "Edit Working Memory"
15515
+ }
15516
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15517
+ /* @__PURE__ */ jsxRuntime.jsx(
15518
+ Button$2,
15519
+ {
15520
+ variant: "default",
15521
+ size: "sm",
15522
+ onClick: async () => {
15523
+ try {
15524
+ await updateWorkingMemory(editValue);
15525
+ setIsEditing(false);
15526
+ } catch (error) {
15527
+ console.error("Failed to update working memory:", error);
15528
+ sonner.toast.error("Failed to update working memory");
15529
+ }
15530
+ },
15531
+ disabled: isUpdating,
15532
+ className: "text-xs",
15533
+ children: isUpdating ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcwIcon, { className: "w-3 h-3 animate-spin" }) : "Save Changes"
15534
+ }
15116
15535
  ),
15117
- children: [
15118
- /* @__PURE__ */ jsxRuntime.jsxs(
15119
- LinkComponent,
15120
- {
15121
- to: `/templates/${template.slug}`,
15122
- className: cn("grid [&:hover_p]:text-icon5", {
15123
- "grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
15124
- }),
15125
- children: [
15126
- template.imageURL && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-hidden"), children: /* @__PURE__ */ jsxRuntime.jsx(
15127
- "div",
15128
- {
15129
- className: "w-full h-full bg-cover thumb transition-scale duration-150",
15130
- style: {
15131
- backgroundImage: `url(${template.imageURL})`
15132
- }
15133
- }
15134
- ) }),
15135
- /* @__PURE__ */ jsxRuntime.jsxs(
15136
- "div",
15137
- {
15138
- className: cn(
15139
- "grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
15140
- "[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
15141
- ),
15142
- children: [
15143
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
15144
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
15145
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
15146
- hasMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
15147
- "ul",
15148
- {
15149
- className: cn(
15150
- "flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
15151
- "[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
15152
- ),
15153
- children: [
15154
- template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
15155
- /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}),
15156
- " ",
15157
- template.agents.length
15158
- ] }),
15159
- template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
15160
- /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}),
15161
- " ",
15162
- template.tools.length
15163
- ] }),
15164
- template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
15165
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.NetworkIcon, {}),
15166
- " ",
15167
- template.networks.length
15168
- ] }),
15169
- template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
15170
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.WorkflowIcon, {}),
15171
- " ",
15172
- template.workflows.length
15173
- ] }),
15174
- template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
15175
- /* @__PURE__ */ jsxRuntime.jsx(McpServerIcon, {}),
15176
- " ",
15177
- template.mcp.length
15178
- ] })
15179
- ]
15180
- }
15181
- ),
15182
- hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsxRuntime.jsx("small", { children: "|" }),
15183
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "", children: provider }, provider)) })
15184
- ] })
15185
- ]
15186
- }
15187
- )
15188
- ]
15189
- }
15190
- ),
15191
- /* @__PURE__ */ jsxRuntime.jsx(
15192
- "a",
15193
- {
15194
- href: template.githubUrl,
15195
- className: cn("group items-center gap-[0.5rem] text-[0.875rem] ml-auto pr-[1rem] hidden", "lg:flex"),
15196
- target: "_blank",
15197
- rel: "noopener noreferrer",
15198
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-[0.5rem] px-[0.5rem] py-[0.25rem] rounded bg-surface1 group-hover:bg-surface2 text-icon3 transition-colors group-hover:text-icon5 ", children: [
15199
- /* @__PURE__ */ jsxRuntime.jsx(GithubIcon, {}),
15200
- " ",
15201
- getRepoName(template.githubUrl)
15202
- ] })
15203
- }
15204
- )
15205
- ]
15206
- },
15207
- template.slug
15208
- );
15209
- }) });
15210
- }
15211
-
15212
- function TemplateInfo({
15213
- title,
15214
- description,
15215
- imageURL,
15216
- githubUrl,
15217
- isLoading,
15218
- infoData,
15219
- templateSlug
15220
- }) {
15221
- const branchName = templateSlug ? `feat/install-template-${templateSlug}` : "feat/install-template-[slug]";
15222
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15223
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid mt-[2rem] items-center"), children: /* @__PURE__ */ jsxRuntime.jsxs(
15224
- "div",
15225
- {
15226
- className: cn(
15227
- "text-[1.5rem] flex items-center gap-[0.75rem]",
15228
- "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
15229
- {
15230
- "[&>svg]:opacity-20": isLoading
15231
- }
15232
- ),
15233
- children: [
15234
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, {}),
15235
- /* @__PURE__ */ jsxRuntime.jsx(
15236
- "h2",
15237
- {
15238
- className: cn({
15239
- "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
15240
- }),
15241
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : title
15242
- }
15243
- )
15244
- ]
15245
- }
15246
- ) }),
15247
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] ", children: [
15248
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid", children: [
15249
15536
  /* @__PURE__ */ jsxRuntime.jsx(
15250
- "p",
15251
- {
15252
- className: cn("mb-[1rem] text-[0.875rem] text-icon4 mt-[.5rem] leading-[1.75]", {
15253
- "bg-surface4 rounded-lg ": isLoading
15254
- }),
15255
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : description
15256
- }
15257
- ),
15258
- !isLoading && templateSlug && /* @__PURE__ */ jsxRuntime.jsxs(
15259
- "div",
15260
- {
15261
- className: cn(
15262
- "bg-surface2 border border-surface4 rounded-lg p-[1rem] mb-[1rem]",
15263
- "flex items-start gap-[0.75rem]"
15264
- ),
15265
- children: [
15266
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-[0.125rem]", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, { className: "w-[1.1em] h-[1.1em] text-blue-500" }) }),
15267
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-[0.5rem]", children: [
15268
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[0.5rem]", children: [
15269
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranchIcon, { className: "w-[1em] h-[1em] text-icon4" }),
15270
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] font-medium text-icon5", children: "A new Git branch will be created" })
15271
- ] }),
15272
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[0.8125rem] text-icon4 space-y-[0.25rem]", children: [
15273
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
15274
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Branch name:" }),
15275
- " ",
15276
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "bg-surface3 px-[0.375rem] py-[0.125rem] rounded text-[0.75rem] font-mono", children: branchName })
15277
- ] }),
15278
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: "This ensures safe installation with easy rollback if needed. Your main branch remains unchanged." })
15279
- ] })
15280
- ] })
15281
- ]
15282
- }
15283
- ),
15284
- githubUrl && /* @__PURE__ */ jsxRuntime.jsxs(
15285
- "a",
15537
+ Button$2,
15286
15538
  {
15287
- href: githubUrl,
15288
- target: "_blank",
15289
- rel: "noopener noreferrer",
15290
- className: "flex items-center gap-[.5rem] mt-auto text-icon3 text-[0.875rem] hover:text-icon5",
15291
- children: [
15292
- /* @__PURE__ */ jsxRuntime.jsx(GithubIcon, {}),
15293
- githubUrl?.split("/")?.pop()
15294
- ]
15539
+ variant: "secondary",
15540
+ size: "sm",
15541
+ onClick: () => {
15542
+ setEditValue(workingMemoryData ?? "");
15543
+ setIsEditing(false);
15544
+ },
15545
+ disabled: isUpdating,
15546
+ className: "text-xs",
15547
+ children: "Cancel"
15295
15548
  }
15296
15549
  )
15297
- ] }),
15298
- infoData && /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: infoData, LinkComponent: lucideReact.Link, labelsAreHidden: true, isLoading })
15550
+ ] }) })
15551
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface3 border border-border1 rounded-lg p-4", children: [
15552
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-icon3 mb-3", children: "Working memory is not enabled for this agent. Enable it to maintain context across conversations." }),
15553
+ /* @__PURE__ */ jsxRuntime.jsxs(
15554
+ "a",
15555
+ {
15556
+ href: "https://mastra.ai/en/docs/memory/working-memory",
15557
+ target: "_blank",
15558
+ rel: "noopener noreferrer",
15559
+ className: "inline-flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors",
15560
+ children: [
15561
+ "Learn about working memory",
15562
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3" })
15563
+ ]
15564
+ }
15565
+ )
15299
15566
  ] })
15300
15567
  ] });
15301
- }
15568
+ };
15302
15569
 
15303
- function TemplateForm({
15304
- providerOptions,
15305
- selectedProvider,
15306
- onProviderChange,
15307
- variables,
15308
- errors,
15309
- handleInstallTemplate,
15310
- handleVariableChange,
15311
- isLoadingEnvVars,
15312
- defaultModelProvider,
15313
- defaultModelId,
15314
- onModelUpdate
15315
- }) {
15316
- return /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-[40rem] my-[1rem] p-[1rem] lg:p-[2rem] mx-auto gap-[2rem] grid", children: [
15317
- /* @__PURE__ */ jsxRuntime.jsxs(
15318
- "h2",
15570
+ const AgentMemoryConfig = ({ agentId }) => {
15571
+ const { data, isLoading } = useMemoryConfig(agentId);
15572
+ const [expandedSections, setExpandedSections] = React.useState(/* @__PURE__ */ new Set(["General", "Semantic Recall"]));
15573
+ const config = data?.config;
15574
+ const configSections = React.useMemo(() => {
15575
+ if (!config) return [];
15576
+ const memoryEnabled = !!config;
15577
+ const sections = [
15319
15578
  {
15320
- className: cn(
15321
- "text-icon4 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
15322
- "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
15323
- ),
15324
- children: [
15325
- "Install Template ",
15326
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageOpenIcon, {})
15579
+ title: "General",
15580
+ items: [
15581
+ { label: "Memory Enabled", value: memoryEnabled, badge: memoryEnabled ? "success" : void 0 },
15582
+ { label: "Last Messages", value: config.lastMessages || 0 },
15583
+ {
15584
+ label: "Auto-generate Titles",
15585
+ value: !!config.threads?.generateTitle,
15586
+ badge: config.threads?.generateTitle ? "info" : void 0
15587
+ }
15327
15588
  ]
15328
15589
  }
15329
- ),
15330
- /* @__PURE__ */ jsxRuntime.jsx(
15331
- SelectField,
15332
- {
15333
- options: providerOptions,
15334
- label: "Template AI Model Provider",
15335
- onValueChange: onProviderChange,
15336
- value: selectedProvider,
15337
- placeholder: "Select"
15338
- }
15339
- ),
15340
- selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15341
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
15342
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxRuntime.jsxs(
15343
- "div",
15590
+ ];
15591
+ if (config.semanticRecall) {
15592
+ const enabled = Boolean(config.semanticRecall);
15593
+ const semanticRecall = typeof config.semanticRecall === "object" ? config.semanticRecall : {};
15594
+ sections.push({
15595
+ title: "Semantic Recall",
15596
+ items: [
15597
+ { label: "Enabled", value: enabled, badge: enabled ? "success" : void 0 },
15598
+ ...enabled ? [
15599
+ { label: "Scope", value: semanticRecall.scope || "thread" },
15600
+ { label: "Top K Results", value: semanticRecall.topK || 5 },
15601
+ {
15602
+ label: "Message Range",
15603
+ value: typeof semanticRecall.messageRange === "object" ? `${semanticRecall.messageRange.before || 0} before, ${semanticRecall.messageRange.after || 0} after` : `${semanticRecall.messageRange || 20} messages`
15604
+ }
15605
+ ] : []
15606
+ ]
15607
+ });
15608
+ }
15609
+ if (config.workingMemory) {
15610
+ sections.push({
15611
+ title: "Working Memory",
15612
+ items: [
15613
+ {
15614
+ label: "Enabled",
15615
+ value: config.workingMemory.enabled,
15616
+ badge: config.workingMemory.enabled ? "success" : void 0
15617
+ },
15618
+ ...config.workingMemory.enabled ? [
15619
+ { label: "Scope", value: config.workingMemory.scope || "thread" },
15620
+ { label: "Template", value: config.workingMemory.template || "default" }
15621
+ ] : []
15622
+ ]
15623
+ });
15624
+ }
15625
+ return sections;
15626
+ }, [config]);
15627
+ const toggleSection = (title) => {
15628
+ const newExpanded = new Set(expandedSections);
15629
+ if (newExpanded.has(title)) {
15630
+ newExpanded.delete(title);
15631
+ } else {
15632
+ newExpanded.add(title);
15633
+ }
15634
+ setExpandedSections(newExpanded);
15635
+ };
15636
+ const renderValue = (value, badge) => {
15637
+ if (typeof value === "boolean") {
15638
+ return /* @__PURE__ */ jsxRuntime.jsx(
15639
+ "span",
15344
15640
  {
15345
15641
  className: cn(
15346
- "flex items-center justify-center col-span-2 text-icon3 text-[0.75rem] gap-[1rem]",
15347
- "[&_svg]:opacity-50 [&_svg]:w-[1.1em] [&_svg]:h-[1.1em]",
15348
- "animate-in fade-in duration-300"
15642
+ "text-xs font-medium px-2 py-0.5 rounded",
15643
+ value ? badge === "info" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400" : "bg-red-500/20 text-red-400"
15349
15644
  ),
15645
+ children: value ? "Yes" : "No"
15646
+ }
15647
+ );
15648
+ }
15649
+ if (badge) {
15650
+ const badgeColors = {
15651
+ success: "bg-green-500/20 text-green-400",
15652
+ info: "bg-blue-500/20 text-blue-400",
15653
+ warning: "bg-yellow-500/20 text-yellow-400"
15654
+ };
15655
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium px-2 py-0.5 rounded", badgeColors[badge]), children: value });
15656
+ }
15657
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-icon3", children: value });
15658
+ };
15659
+ if (isLoading) {
15660
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-32 w-full" }) });
15661
+ }
15662
+ if (!config || configSections.length === 0) {
15663
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
15664
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5 mb-3", children: "Memory Configuration" }),
15665
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-icon3", children: "No memory configuration available" })
15666
+ ] });
15667
+ }
15668
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
15669
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5 mb-3", children: "Memory Configuration" }),
15670
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: configSections.map((section) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-border1 rounded-lg bg-surface3", children: [
15671
+ /* @__PURE__ */ jsxRuntime.jsxs(
15672
+ "button",
15673
+ {
15674
+ onClick: () => toggleSection(section.title),
15675
+ className: "w-full px-3 py-2 flex items-center justify-between hover:bg-surface4 transition-colors rounded-t-lg",
15350
15676
  children: [
15351
- /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}),
15352
- " Loading variables..."
15677
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-icon5", children: section.title }),
15678
+ expandedSections.has(section.title) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 text-icon3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3 text-icon3" })
15353
15679
  ]
15354
15680
  }
15355
- ) : Object.entries(variables).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
15356
- /* @__PURE__ */ jsxRuntime.jsx(
15357
- InputField,
15358
- {
15359
- name: `env-${key}`,
15360
- labelIsHidden: true,
15361
- label: "Key",
15362
- value: key,
15363
- disabled: true,
15364
- className: "w-full"
15365
- }
15366
- ),
15367
- /* @__PURE__ */ jsxRuntime.jsx(
15368
- InputField,
15369
- {
15370
- name: key,
15681
+ ),
15682
+ expandedSections.has(section.title) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2 space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-1", children: [
15683
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-icon3", children: item.label }),
15684
+ renderValue(item.value || "", item.badge)
15685
+ ] }, `${section.title}-${item.label}`)) })
15686
+ ] }, section.title)) })
15687
+ ] });
15688
+ };
15689
+
15690
+ const formatRelativeTime = (date) => {
15691
+ const now = /* @__PURE__ */ new Date();
15692
+ const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
15693
+ if (seconds < 60) return "just now";
15694
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
15695
+ if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
15696
+ if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
15697
+ return date.toLocaleDateString();
15698
+ };
15699
+ const MemorySearch = ({
15700
+ searchMemory,
15701
+ onResultClick,
15702
+ className,
15703
+ currentThreadId,
15704
+ chatInputValue
15705
+ }) => {
15706
+ const [query, setQuery] = React.useState("");
15707
+ const [results, setResults] = React.useState([]);
15708
+ const [isSearching, setIsSearching] = React.useState(false);
15709
+ const [isOpen, setIsOpen] = React.useState(false);
15710
+ const [error, setError] = React.useState(null);
15711
+ const searchTimeoutRef = React.useRef(void 0);
15712
+ const dropdownRef = React.useRef(null);
15713
+ const prevThreadIdRef = React.useRef(currentThreadId);
15714
+ const lastSearchTimeRef = React.useRef(0);
15715
+ const pendingSearchRef = React.useRef(null);
15716
+ const handleSearch = React.useCallback(
15717
+ async (searchQuery) => {
15718
+ if (!searchQuery.trim()) {
15719
+ setError(null);
15720
+ return;
15721
+ }
15722
+ setIsSearching(true);
15723
+ setError(null);
15724
+ try {
15725
+ const response = await searchMemory(searchQuery);
15726
+ setResults(response.results);
15727
+ setIsOpen((prev) => prev || response.results.length > 0);
15728
+ } catch (err) {
15729
+ setError("Failed to search memory");
15730
+ console.error("Memory search error:", err);
15731
+ } finally {
15732
+ setIsSearching(false);
15733
+ }
15734
+ },
15735
+ [searchMemory]
15736
+ );
15737
+ const handleInputChange = React.useCallback(
15738
+ (e) => {
15739
+ const value = e.target.value;
15740
+ setQuery(value);
15741
+ if (searchTimeoutRef.current) {
15742
+ clearTimeout(searchTimeoutRef.current);
15743
+ }
15744
+ if (value.trim()) {
15745
+ const now = Date.now();
15746
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
15747
+ if (timeSinceLastSearch >= 500) {
15748
+ setIsSearching(true);
15749
+ handleSearch(value);
15750
+ lastSearchTimeRef.current = now;
15751
+ } else {
15752
+ setIsSearching(true);
15753
+ pendingSearchRef.current = value;
15754
+ const remainingTime = 500 - timeSinceLastSearch;
15755
+ searchTimeoutRef.current = setTimeout(() => {
15756
+ if (pendingSearchRef.current) {
15757
+ handleSearch(pendingSearchRef.current);
15758
+ lastSearchTimeRef.current = Date.now();
15759
+ pendingSearchRef.current = null;
15760
+ }
15761
+ }, remainingTime);
15762
+ }
15763
+ } else {
15764
+ setResults([]);
15765
+ setIsOpen(false);
15766
+ setIsSearching(false);
15767
+ pendingSearchRef.current = null;
15768
+ }
15769
+ },
15770
+ [handleSearch]
15771
+ );
15772
+ const handleKeyDown = React.useCallback(
15773
+ (e) => {
15774
+ if (e.key === "Enter") {
15775
+ e.preventDefault();
15776
+ if (searchTimeoutRef.current) {
15777
+ clearTimeout(searchTimeoutRef.current);
15778
+ }
15779
+ handleSearch(query);
15780
+ }
15781
+ },
15782
+ [query, handleSearch]
15783
+ );
15784
+ React.useEffect(() => {
15785
+ return () => {
15786
+ if (searchTimeoutRef.current) {
15787
+ clearTimeout(searchTimeoutRef.current);
15788
+ }
15789
+ };
15790
+ }, []);
15791
+ React.useEffect(() => {
15792
+ const handleClickOutside = (event) => {
15793
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
15794
+ setIsOpen(false);
15795
+ }
15796
+ };
15797
+ document.addEventListener("mousedown", handleClickOutside);
15798
+ return () => document.removeEventListener("mousedown", handleClickOutside);
15799
+ }, []);
15800
+ React.useEffect(() => {
15801
+ if (prevThreadIdRef.current !== currentThreadId && query.trim()) {
15802
+ handleSearch(query);
15803
+ }
15804
+ prevThreadIdRef.current = currentThreadId;
15805
+ }, [currentThreadId, query, handleSearch]);
15806
+ React.useEffect(() => {
15807
+ if (chatInputValue !== void 0 && chatInputValue !== query) {
15808
+ setQuery(chatInputValue);
15809
+ if (searchTimeoutRef.current) {
15810
+ clearTimeout(searchTimeoutRef.current);
15811
+ }
15812
+ if (chatInputValue.trim()) {
15813
+ const now = Date.now();
15814
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
15815
+ if (timeSinceLastSearch >= 500) {
15816
+ setIsSearching(true);
15817
+ handleSearch(chatInputValue);
15818
+ lastSearchTimeRef.current = now;
15819
+ } else {
15820
+ setIsSearching(true);
15821
+ pendingSearchRef.current = chatInputValue;
15822
+ const remainingTime = 500 - timeSinceLastSearch;
15823
+ searchTimeoutRef.current = setTimeout(() => {
15824
+ if (pendingSearchRef.current) {
15825
+ handleSearch(pendingSearchRef.current);
15826
+ lastSearchTimeRef.current = Date.now();
15827
+ pendingSearchRef.current = null;
15828
+ }
15829
+ }, remainingTime);
15830
+ }
15831
+ } else {
15832
+ setResults([]);
15833
+ setIsOpen(false);
15834
+ setIsSearching(false);
15835
+ pendingSearchRef.current = null;
15836
+ }
15837
+ }
15838
+ return () => {
15839
+ if (searchTimeoutRef.current) {
15840
+ clearTimeout(searchTimeoutRef.current);
15841
+ }
15842
+ };
15843
+ }, [chatInputValue]);
15844
+ const handleResultClick = (messageId, threadId) => {
15845
+ onResultClick?.(messageId, threadId);
15846
+ };
15847
+ const clearSearch = () => {
15848
+ setQuery("");
15849
+ setResults([]);
15850
+ setIsOpen(false);
15851
+ setError(null);
15852
+ if (searchTimeoutRef.current) {
15853
+ clearTimeout(searchTimeoutRef.current);
15854
+ }
15855
+ };
15856
+ const truncateContent = (content, maxLength = 100) => {
15857
+ if (content.length <= maxLength) return content;
15858
+ return content.substring(0, maxLength) + "...";
15859
+ };
15860
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), ref: dropdownRef, children: [
15861
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
15862
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
15863
+ /* @__PURE__ */ jsxRuntime.jsx(
15864
+ Input,
15865
+ {
15866
+ type: "text",
15867
+ value: query,
15868
+ onChange: handleInputChange,
15869
+ onKeyDown: handleKeyDown,
15870
+ placeholder: "Search memory...",
15871
+ className: "pl-10 pr-10 bg-surface3 border-border1"
15872
+ }
15873
+ ),
15874
+ query && /* @__PURE__ */ jsxRuntime.jsx(
15875
+ Button$2,
15876
+ {
15877
+ onClick: clearSearch,
15878
+ variant: "ghost",
15879
+ size: "sm",
15880
+ className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
15881
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
15882
+ }
15883
+ )
15884
+ ] }),
15885
+ (isOpen || query && (isSearching || results.length === 0)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex-1 bg-surface3 border border-border1 rounded-lg shadow-lg overflow-y-auto", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-red-500", children: error }) }) : isSearching && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: "Searching..." }) }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon3", children: [
15886
+ 'No results found for "',
15887
+ query,
15888
+ '"'
15889
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
15890
+ "button",
15891
+ {
15892
+ onClick: () => handleResultClick(result.id, result.threadId),
15893
+ className: cn(
15894
+ "w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
15895
+ result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
15896
+ ),
15897
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
15898
+ result.context?.before && result.context.before.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.before.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
15899
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
15900
+ msg.role,
15901
+ ":"
15902
+ ] }),
15903
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
15904
+ ] }, idx)) }),
15905
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
15906
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
15907
+ /* @__PURE__ */ jsxRuntime.jsx(
15908
+ "span",
15909
+ {
15910
+ className: cn(
15911
+ "text-xs font-medium px-2 py-0.5 rounded",
15912
+ result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
15913
+ ),
15914
+ children: result.role
15915
+ }
15916
+ ),
15917
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
15918
+ result.threadTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
15919
+ /* @__PURE__ */ jsxRuntime.jsxs(
15920
+ Txt,
15921
+ {
15922
+ variant: "ui-xs",
15923
+ className: cn(
15924
+ "truncate max-w-[150px]",
15925
+ result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
15926
+ ),
15927
+ title: result.threadTitle,
15928
+ children: [
15929
+ "• ",
15930
+ result.threadTitle
15931
+ ]
15932
+ }
15933
+ ),
15934
+ result.threadId !== currentThreadId && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 text-blue-400" })
15935
+ ] })
15936
+ ] }),
15937
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
15938
+ ] }) }),
15939
+ result.context?.after && result.context.after.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.after.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
15940
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
15941
+ msg.role,
15942
+ ":"
15943
+ ] }),
15944
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
15945
+ ] }, idx)) })
15946
+ ] })
15947
+ },
15948
+ result.id
15949
+ )) }) })
15950
+ ] });
15951
+ };
15952
+
15953
+ function AgentMemory({ agentId, threadId }) {
15954
+ const { threadInput: chatInputValue } = useThreadInput();
15955
+ const { paths, navigate } = useLinkComponent();
15956
+ const [searchScope, setSearchScope] = React.useState(null);
15957
+ const { data } = useMemoryConfig(agentId);
15958
+ const config = data?.config;
15959
+ const isSemanticRecallEnabled = Boolean(config?.semanticRecall);
15960
+ const { searchMemory } = useMemorySearch({
15961
+ agentId: agentId || "",
15962
+ resourceId: agentId || "",
15963
+ // In playground, agentId is the resourceId
15964
+ threadId
15965
+ });
15966
+ const searchSemanticRecall = React.useCallback(
15967
+ async (query) => {
15968
+ const result = await searchMemory(query, { lastMessages: 0 });
15969
+ if (result.searchScope) {
15970
+ setSearchScope(result.searchScope);
15971
+ }
15972
+ return result;
15973
+ },
15974
+ [searchMemory]
15975
+ );
15976
+ const handleResultClick = React.useCallback(
15977
+ (messageId, resultThreadId) => {
15978
+ if (resultThreadId && resultThreadId !== threadId) {
15979
+ navigate(paths.agentThreadLink(agentId, resultThreadId, messageId));
15980
+ } else {
15981
+ const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
15982
+ if (messageElement) {
15983
+ messageElement.scrollIntoView({ behavior: "smooth", block: "center" });
15984
+ messageElement.classList.add("bg-surface4");
15985
+ setTimeout(() => {
15986
+ messageElement.classList.remove("bg-surface4");
15987
+ }, 2e3);
15988
+ }
15989
+ }
15990
+ },
15991
+ [agentId, threadId, navigate]
15992
+ );
15993
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
15994
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border1", children: [
15995
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
15996
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5", children: "Semantic Recall" }),
15997
+ searchScope && /* @__PURE__ */ jsxRuntime.jsx(
15998
+ "span",
15999
+ {
16000
+ className: cn(
16001
+ "text-xs font-medium px-2 py-0.5 rounded",
16002
+ searchScope === "resource" ? "bg-purple-500/20 text-purple-400" : "bg-blue-500/20 text-blue-400"
16003
+ ),
16004
+ title: searchScope === "resource" ? "Searching across all threads" : "Searching within current thread only",
16005
+ children: searchScope
16006
+ }
16007
+ )
16008
+ ] }) }),
16009
+ isSemanticRecallEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
16010
+ MemorySearch,
16011
+ {
16012
+ searchMemory: searchSemanticRecall,
16013
+ onResultClick: handleResultClick,
16014
+ currentThreadId: threadId,
16015
+ className: "w-full",
16016
+ chatInputValue
16017
+ }
16018
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface3 border border-border1 rounded-lg p-4", children: [
16019
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-icon3 mb-3", children: "Semantic recall is not enabled for this agent. Enable it to search through conversation history." }),
16020
+ /* @__PURE__ */ jsxRuntime.jsxs(
16021
+ "a",
16022
+ {
16023
+ href: "https://mastra.ai/en/docs/memory/semantic-recall",
16024
+ target: "_blank",
16025
+ rel: "noopener noreferrer",
16026
+ className: "inline-flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors",
16027
+ children: [
16028
+ "Learn about semantic recall",
16029
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3" })
16030
+ ]
16031
+ }
16032
+ )
16033
+ ] })
16034
+ ] }),
16035
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
16036
+ /* @__PURE__ */ jsxRuntime.jsx(AgentWorkingMemory, { agentId }),
16037
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(AgentMemoryConfig, { agentId }) })
16038
+ ] })
16039
+ ] });
16040
+ }
16041
+
16042
+ function CurrentInstructions({
16043
+ instructions,
16044
+ enhancedPrompt,
16045
+ isEnhancing,
16046
+ userComment,
16047
+ onEnhance,
16048
+ onCancel,
16049
+ onSave,
16050
+ onCommentChange,
16051
+ onShowHistory
16052
+ }) {
16053
+ const currentContent = enhancedPrompt || extractPrompt(instructions);
16054
+ const { isCopied, handleCopy } = useCopyToClipboard({ text: currentContent || "" });
16055
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
16056
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4 pb-2", children: enhancedPrompt ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
16057
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
16058
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "text-accent2" }) }) }),
16059
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Discard prompt suggestions" })
16060
+ ] }) }),
16061
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onSave, disabled: !enhancedPrompt, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
16062
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "text-accent1" }) }) }),
16063
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Save prompt suggestions" })
16064
+ ] }) })
16065
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onShowHistory, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
16066
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg text-icon3 hover:text-icon6", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileClock, {}) }) }),
16067
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Version history" })
16068
+ ] }) }) }),
16069
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("p-[1px] rounded-lg overflow-hidden relative"), children: [
16070
+ /* @__PURE__ */ jsxRuntime.jsx(
16071
+ "div",
16072
+ {
16073
+ className: clsx(
16074
+ "absolute inset-0 bg-surface4 transition-all",
16075
+ enhancedPrompt && "bg-gradient-to-br from-accent1 to-accent3"
16076
+ )
16077
+ }
16078
+ ),
16079
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 bg-surface4 rounded-lg", children: [
16080
+ /* @__PURE__ */ jsxRuntime.jsx(
16081
+ CodeDisplay,
16082
+ {
16083
+ content: currentContent || "",
16084
+ isCopied,
16085
+ isDraft: !!enhancedPrompt,
16086
+ onCopy: () => currentContent && handleCopy(),
16087
+ className: "border-none bg-surface4 text-ui-sm p-2 !h-[260px]"
16088
+ }
16089
+ ),
16090
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between rounded-lg border border-border1 bg-surface5 shadow-lg disabled:bg-surface3 text-icon6 w-full py-2 px-3 gap-3 relative z-10", children: [
16091
+ /* @__PURE__ */ jsxRuntime.jsx(
16092
+ "textarea",
16093
+ {
16094
+ value: userComment,
16095
+ onChange: (e) => onCommentChange(e.target.value),
16096
+ placeholder: "Add your comments or requirements for enhancing your agent's prompt...",
16097
+ className: "resize-none text-ui-sm w-full placeholder:text-icon3 bg-transparent block disabled:text-icon3",
16098
+ disabled: Boolean(isEnhancing || enhancedPrompt)
16099
+ }
16100
+ ),
16101
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onEnhance, disabled: isEnhancing || !instructions || Boolean(enhancedPrompt), children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
16102
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "text-icon3 hover:text-icon6 disabled:hover:text-icon3", children: isEnhancing ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wand2, {}) }) }),
16103
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: isEnhancing ? "Enhancing..." : "Enhance prompt" })
16104
+ ] }) })
16105
+ ] }) })
16106
+ ] })
16107
+ ] }) })
16108
+ ] });
16109
+ }
16110
+
16111
+ function usePromptEnhancer({
16112
+ agentId,
16113
+ instructions,
16114
+ versions,
16115
+ onVersionCreate,
16116
+ onVersionUpdate
16117
+ }) {
16118
+ const [enhancedPrompt, setEnhancedPrompt] = React.useState("");
16119
+ const [explanation, setExplanation] = React.useState("");
16120
+ const [isEnhancing, setIsEnhancing] = React.useState(false);
16121
+ const [userComment, setUserComment] = React.useState("");
16122
+ const enhancePrompt = async () => {
16123
+ if (!instructions) return;
16124
+ setIsEnhancing(true);
16125
+ try {
16126
+ const response = await fetch(`/api/agents/${agentId}/instructions/enhance`, {
16127
+ method: "POST",
16128
+ headers: {
16129
+ "Content-Type": "application/json",
16130
+ "x-mastra-dev-playground": "true"
16131
+ },
16132
+ body: JSON.stringify({
16133
+ instructions,
16134
+ comment: userComment
16135
+ })
16136
+ });
16137
+ if (!response.ok) {
16138
+ throw new Error("Failed to enhance prompt");
16139
+ }
16140
+ const data = await response.json();
16141
+ setEnhancedPrompt(data.new_prompt);
16142
+ setExplanation(data.explanation);
16143
+ setUserComment("");
16144
+ } catch (error) {
16145
+ console.error("Failed to enhance prompt:", error);
16146
+ } finally {
16147
+ setIsEnhancing(false);
16148
+ }
16149
+ };
16150
+ const clearEnhancement = () => {
16151
+ setEnhancedPrompt("");
16152
+ setExplanation("");
16153
+ };
16154
+ const applyChanges = () => {
16155
+ if (!enhancedPrompt) return;
16156
+ const draftIndex = versions.findIndex((v) => v.status === "draft");
16157
+ if (draftIndex !== -1) {
16158
+ onVersionUpdate(draftIndex, {
16159
+ content: enhancedPrompt,
16160
+ analysis: explanation,
16161
+ status: "published",
16162
+ timestamp: /* @__PURE__ */ new Date()
16163
+ });
16164
+ } else {
16165
+ const newVersion = {
16166
+ content: enhancedPrompt,
16167
+ timestamp: /* @__PURE__ */ new Date(),
16168
+ analysis: explanation,
16169
+ status: "published"
16170
+ };
16171
+ onVersionCreate(newVersion);
16172
+ }
16173
+ clearEnhancement();
16174
+ };
16175
+ return {
16176
+ enhancedPrompt,
16177
+ explanation,
16178
+ isEnhancing,
16179
+ userComment,
16180
+ enhancePrompt,
16181
+ setUserComment,
16182
+ clearEnhancement,
16183
+ applyChanges
16184
+ };
16185
+ }
16186
+
16187
+ function usePromptVersions(agentId, instructions) {
16188
+ const [versions, setVersions] = React.useState([]);
16189
+ const [copiedVersions, setCopiedVersions] = React.useState({});
16190
+ const [isUpdating, setIsUpdating] = React.useState(false);
16191
+ const [versionToDelete, setVersionToDelete] = React.useState(null);
16192
+ const client = react$3.useMastraClient();
16193
+ const { runtimeContext } = usePlaygroundStore();
16194
+ const fetchEvalResults = async () => {
16195
+ try {
16196
+ const response = await client.getAgent(agentId).liveEvals(runtimeContext);
16197
+ return response?.evals;
16198
+ } catch (error) {
16199
+ console.error("Failed to fetch eval results:", error);
16200
+ return [];
16201
+ }
16202
+ };
16203
+ React.useEffect(() => {
16204
+ const loadVersions = async () => {
16205
+ const evals = await fetchEvalResults();
16206
+ const storedVersions = localStorage.getItem(`agent-${agentId}-versions`);
16207
+ if (storedVersions) {
16208
+ const parsedVersions = JSON.parse(storedVersions);
16209
+ const originalVersion = parsedVersions.find((v) => v.status === "original");
16210
+ if (instructions && originalVersion && originalVersion.content !== instructions) {
16211
+ const originalEvals = evals?.filter((m) => m.meta.instructions === instructions);
16212
+ const newVersions = [
16213
+ {
16214
+ content: instructions,
16215
+ timestamp: /* @__PURE__ */ new Date(),
16216
+ analysis: "Original instructions",
16217
+ status: "original",
16218
+ evals: originalEvals
16219
+ }
16220
+ ];
16221
+ newVersions[0].evals = evals;
16222
+ setVersions(newVersions);
16223
+ localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(newVersions));
16224
+ } else {
16225
+ const updatedVersions = await Promise.all(
16226
+ parsedVersions.map(async (v) => {
16227
+ const originalEvals = evals?.filter((m) => m.meta.instructions === v.content);
16228
+ const version = {
16229
+ ...v,
16230
+ timestamp: new Date(v.timestamp),
16231
+ status: v.content === instructions ? "active" : v.status === "active" ? "published" : v.status
16232
+ };
16233
+ return { ...version, evals: originalEvals };
16234
+ })
16235
+ );
16236
+ setVersions(updatedVersions);
16237
+ }
16238
+ } else if (instructions) {
16239
+ const initialVersions = [
16240
+ {
16241
+ content: instructions,
16242
+ timestamp: /* @__PURE__ */ new Date(),
16243
+ analysis: "Original instructions",
16244
+ status: "original",
16245
+ evals: []
16246
+ }
16247
+ ];
16248
+ const originalEvals = evals?.filter((m) => m.meta.instructions === instructions);
16249
+ initialVersions[0].evals = originalEvals;
16250
+ setVersions(initialVersions);
16251
+ localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(initialVersions));
16252
+ }
16253
+ };
16254
+ loadVersions();
16255
+ }, [instructions, agentId]);
16256
+ React.useEffect(() => {
16257
+ if (versions.length > 0) {
16258
+ localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(versions));
16259
+ }
16260
+ }, [versions, agentId]);
16261
+ const copyToClipboard = async (text, versionIndex) => {
16262
+ setCopiedVersions((prev) => ({ ...prev, [versionIndex]: true }));
16263
+ const timer = setTimeout(() => {
16264
+ setCopiedVersions((prev) => ({ ...prev, [versionIndex]: false }));
16265
+ }, 1e3);
16266
+ return () => clearTimeout(timer);
16267
+ };
16268
+ const setVersionActive = async (version, index) => {
16269
+ setIsUpdating(true);
16270
+ try {
16271
+ const response = await fetch(`/api/agents/${agentId}/instructions`, {
16272
+ method: "POST",
16273
+ headers: {
16274
+ "Content-Type": "application/json",
16275
+ "x-mastra-dev-playground": "true"
16276
+ },
16277
+ body: JSON.stringify({
16278
+ instructions: version.content
16279
+ })
16280
+ });
16281
+ if (!response.ok) {
16282
+ throw new Error("Failed to update instructions");
16283
+ }
16284
+ setVersions(
16285
+ (prev) => prev.map((v, i) => ({
16286
+ ...v,
16287
+ status: i === index ? "active" : v.status === "active" ? "published" : v.status
16288
+ }))
16289
+ );
16290
+ } catch (error) {
16291
+ console.error("Failed to set version as active:", error);
16292
+ } finally {
16293
+ setIsUpdating(false);
16294
+ }
16295
+ };
16296
+ const deleteVersion = (index) => {
16297
+ setVersions((prev) => prev.filter((_, i) => i !== index));
16298
+ setVersionToDelete(null);
16299
+ };
16300
+ const updateVersion = async (index, updates) => {
16301
+ const updatedVersion = {
16302
+ ...versions[index],
16303
+ ...updates
16304
+ };
16305
+ setVersions((prev) => prev.map((version, i) => i === index ? updatedVersion : version));
16306
+ };
16307
+ return {
16308
+ versions,
16309
+ copiedVersions,
16310
+ isUpdating,
16311
+ versionToDelete,
16312
+ setVersions,
16313
+ setVersionToDelete,
16314
+ copyToClipboard,
16315
+ setVersionActive,
16316
+ deleteVersion,
16317
+ updateVersion
16318
+ };
16319
+ }
16320
+
16321
+ function VersionActions({ version, index, isUpdating, onSetActive, onDelete }) {
16322
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1", children: [
16323
+ version.status !== "active" && version.status !== "draft" && /* @__PURE__ */ jsxRuntime.jsx(
16324
+ Button$2,
16325
+ {
16326
+ variant: "ghost",
16327
+ size: "sm",
16328
+ className: "h-6 px-2 hover:bg-mastra-bg-3 relative group",
16329
+ onClick: (e) => {
16330
+ e.stopPropagation();
16331
+ onSetActive(version, index);
16332
+ },
16333
+ disabled: isUpdating,
16334
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-3 w-3" })
16335
+ }
16336
+ ),
16337
+ index !== 0 && version.status !== "active" && /* @__PURE__ */ jsxRuntime.jsx(
16338
+ Button$2,
16339
+ {
16340
+ variant: "ghost",
16341
+ size: "sm",
16342
+ className: "h-6 px-2 hover:bg-mastra-bg-3 relative group",
16343
+ onClick: (e) => {
16344
+ e.stopPropagation();
16345
+ onDelete(index);
16346
+ },
16347
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3 text-red-400 hover:text-red-500" })
16348
+ }
16349
+ )
16350
+ ] });
16351
+ }
16352
+
16353
+ function VersionItem({
16354
+ version,
16355
+ index,
16356
+ isExpanded,
16357
+ isUpdating,
16358
+ onToggleExpand,
16359
+ onToggleAnalysis,
16360
+ onSetActive,
16361
+ onDelete
16362
+ }) {
16363
+ const [showEvals, setShowEvals] = React.useState(false);
16364
+ const [showInstructions, setShowInstructions] = React.useState(true);
16365
+ const [showAnalysis, setShowAnalysis] = React.useState(false);
16366
+ const { handleCopy, isCopied } = useCopyToClipboard({
16367
+ text: version.content
16368
+ });
16369
+ const formatText = (text) => {
16370
+ return text.replace(/\\n/g, "\n");
16371
+ };
16372
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16373
+ "div",
16374
+ {
16375
+ className: `rounded-md border ${isExpanded ? "border-mastra-purple/30" : "border-mastra-bg-3"} bg-mastra-bg-2`,
16376
+ children: [
16377
+ /* @__PURE__ */ jsxRuntime.jsxs(
16378
+ "div",
16379
+ {
16380
+ className: "p-2 flex items-center justify-between cursor-pointer hover:bg-mastra-bg-3/50",
16381
+ onClick: onToggleExpand,
16382
+ children: [
16383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
16384
+ /* @__PURE__ */ jsxRuntime.jsx(
16385
+ lucideReact.ChevronRight,
16386
+ {
16387
+ className: `h-3 w-3 transition-transform ${isExpanded ? "rotate-90 text-mastra-purple" : ""}`
16388
+ }
16389
+ ),
16390
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
16391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
16392
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-mastra-el-4", children: [
16393
+ "Version ",
16394
+ index + 1
16395
+ ] }),
16396
+ version.status === "active" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Active" }),
16397
+ version.status === "original" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-blue-500/20 text-blue-500", children: "Original" }),
16398
+ version.status === "draft" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-yellow-500/20 text-yellow-500", children: "Draft" })
16399
+ ] }),
16400
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-mastra-el-3", children: version.timestamp.toLocaleString() })
16401
+ ] })
16402
+ ] }),
16403
+ /* @__PURE__ */ jsxRuntime.jsx(
16404
+ VersionActions,
16405
+ {
16406
+ version,
16407
+ index,
16408
+ isUpdating,
16409
+ onSetActive,
16410
+ onDelete
16411
+ }
16412
+ )
16413
+ ]
16414
+ }
16415
+ ),
16416
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-[250px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-2 pb-2 space-y-2", children: [
16417
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
16418
+ /* @__PURE__ */ jsxRuntime.jsxs(
16419
+ "div",
16420
+ {
16421
+ className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md mb-2",
16422
+ onClick: (e) => {
16423
+ e.stopPropagation();
16424
+ setShowInstructions(!showInstructions);
16425
+ },
16426
+ children: [
16427
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showInstructions ? "rotate-90" : ""}` }),
16428
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-mastra-el-4", children: "Instructions" })
16429
+ ]
16430
+ }
16431
+ ),
16432
+ showInstructions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-mastra-bg-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDisplay, { content: formatText(version.content), isCopied, onCopy: handleCopy }) }) })
16433
+ ] }),
16434
+ version.analysis && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
16435
+ /* @__PURE__ */ jsxRuntime.jsxs(
16436
+ "div",
16437
+ {
16438
+ className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md mb-2",
16439
+ onClick: (e) => {
16440
+ e.stopPropagation();
16441
+ setShowAnalysis(!showAnalysis);
16442
+ },
16443
+ children: [
16444
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showAnalysis ? "rotate-90" : ""}` }),
16445
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-mastra-el-4", children: "Analysis" })
16446
+ ]
16447
+ }
16448
+ ),
16449
+ showAnalysis && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-mastra-bg-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-[10px] text-mastra-el-4 whitespace-pre-wrap font-mono", children: formatText(version.analysis || "") }) }) })
16450
+ ] }),
16451
+ version.evals && version.evals.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
16452
+ /* @__PURE__ */ jsxRuntime.jsxs(
16453
+ "div",
16454
+ {
16455
+ className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md",
16456
+ onClick: (e) => {
16457
+ e.stopPropagation();
16458
+ setShowEvals(!showEvals);
16459
+ },
16460
+ children: [
16461
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showEvals ? "rotate-90" : ""}` }),
16462
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-mastra-el-4", children: [
16463
+ "Evaluations (",
16464
+ version.evals.length,
16465
+ ")"
16466
+ ] })
16467
+ ]
16468
+ }
16469
+ ),
16470
+ showEvals && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 pr-4", children: version.evals.map((metric, evalIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-mastra-bg-3 p-1.5 text-[10px]", children: [
16471
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
16472
+ /* @__PURE__ */ jsxRuntime.jsx(
16473
+ "span",
16474
+ {
16475
+ className: `px-1.5 py-0.5 rounded-full min-w-[32px] text-center ${metric.result.score >= 0.7 ? "bg-green-500/20 text-green-500" : metric.result.score >= 0.4 ? "bg-yellow-500/20 text-yellow-500" : "bg-red-500/20 text-red-500"}`,
16476
+ children: metric.result.score.toFixed(2)
16477
+ }
16478
+ ),
16479
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 text-[9px]", children: new Date(metric.createdAt).toLocaleTimeString() })
16480
+ ] }) }),
16481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 space-y-1", children: [
16482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [
16483
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 shrink-0", children: "→" }),
16484
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-4", children: metric.input })
16485
+ ] }),
16486
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [
16487
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 shrink-0", children: "←" }),
16488
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-4", children: metric.output })
16489
+ ] }),
16490
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 text-[9px] text-mastra-el-3", children: [
16491
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: "⚬" }),
16492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: metric.result.info.reason })
16493
+ ] })
16494
+ ] })
16495
+ ] }, evalIndex)) }) })
16496
+ ] })
16497
+ ] }) })
16498
+ ]
16499
+ }
16500
+ );
16501
+ }
16502
+
16503
+ function VersionHistory({
16504
+ versions,
16505
+ isUpdating,
16506
+ copiedVersions,
16507
+ onCopy,
16508
+ onSetActive,
16509
+ onDelete
16510
+ }) {
16511
+ const [expandedVersion, setExpandedVersion] = React.useState(null);
16512
+ const [expandedAnalysis, setExpandedAnalysis] = React.useState(null);
16513
+ return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2 pr-4", children: versions.map((version, index) => /* @__PURE__ */ jsxRuntime.jsx(
16514
+ VersionItem,
16515
+ {
16516
+ version,
16517
+ index,
16518
+ isExpanded: expandedVersion === index,
16519
+ isUpdating,
16520
+ copiedVersions,
16521
+ onToggleExpand: () => {
16522
+ if (expandedVersion === index) {
16523
+ return setExpandedVersion(null);
16524
+ }
16525
+ setExpandedVersion(index);
16526
+ },
16527
+ onToggleAnalysis: () => {
16528
+ if (expandedAnalysis === index) {
16529
+ return setExpandedAnalysis(null);
16530
+ }
16531
+ setExpandedAnalysis(index);
16532
+ },
16533
+ onCopy,
16534
+ onSetActive,
16535
+ onDelete
16536
+ },
16537
+ index
16538
+ )) }) });
16539
+ }
16540
+
16541
+ const VersionHistoryDialog = ({
16542
+ open,
16543
+ onOpenChange,
16544
+ onDelete,
16545
+ onSetActive,
16546
+ versions,
16547
+ isUpdating
16548
+ }) => {
16549
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "bg-surface4", children: [
16550
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
16551
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Version History" }),
16552
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "View the history of changes to the agent's instructions." })
16553
+ ] }),
16554
+ /* @__PURE__ */ jsxRuntime.jsx(
16555
+ VersionHistory,
16556
+ {
16557
+ versions,
16558
+ isUpdating,
16559
+ copiedVersions: {},
16560
+ onCopy: async (content, key) => {
16561
+ await navigator.clipboard.writeText(content);
16562
+ },
16563
+ onSetActive,
16564
+ onDelete
16565
+ }
16566
+ )
16567
+ ] }) });
16568
+ };
16569
+
16570
+ function AgentPromptEnhancer({ agentId }) {
16571
+ const { data: agent } = useAgent(agentId);
16572
+ const [showVersionHistoryDialog, setShowVersionHistoryDialog] = React.useState(false);
16573
+ const formattedInstructions = extractPrompt(agent?.instructions || "");
16574
+ const {
16575
+ versions,
16576
+ isUpdating,
16577
+ versionToDelete,
16578
+ setVersions,
16579
+ setVersionToDelete,
16580
+ deleteVersion,
16581
+ updateVersion,
16582
+ setVersionActive
16583
+ } = usePromptVersions(agentId, formattedInstructions);
16584
+ const { enhancedPrompt, isEnhancing, userComment, enhancePrompt, setUserComment, clearEnhancement, applyChanges } = usePromptEnhancer({
16585
+ agentId,
16586
+ instructions: formattedInstructions,
16587
+ versions,
16588
+ onVersionCreate: (newVersion) => {
16589
+ setVersions((prev) => [...prev, newVersion]);
16590
+ },
16591
+ onVersionUpdate: updateVersion
16592
+ });
16593
+ if (!agent) return null;
16594
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16595
+ /* @__PURE__ */ jsxRuntime.jsx(
16596
+ CurrentInstructions,
16597
+ {
16598
+ instructions: agent.instructions,
16599
+ enhancedPrompt,
16600
+ isEnhancing,
16601
+ userComment,
16602
+ onEnhance: enhancePrompt,
16603
+ onCancel: clearEnhancement,
16604
+ onSave: applyChanges,
16605
+ onCommentChange: setUserComment,
16606
+ agentId,
16607
+ onShowHistory: () => setShowVersionHistoryDialog(true)
16608
+ }
16609
+ ),
16610
+ /* @__PURE__ */ jsxRuntime.jsx(
16611
+ VersionHistoryDialog,
16612
+ {
16613
+ versions,
16614
+ isUpdating,
16615
+ onSetActive: setVersionActive,
16616
+ onDelete: setVersionToDelete,
16617
+ open: showVersionHistoryDialog,
16618
+ onOpenChange: setShowVersionHistoryDialog
16619
+ }
16620
+ ),
16621
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog, { open: versionToDelete !== null, onOpenChange: () => setVersionToDelete(null), children: /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Content, { children: [
16622
+ /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Header, { children: [
16623
+ /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Title, { children: [
16624
+ "Delete Version ",
16625
+ versionToDelete !== null ? versionToDelete + 1 : ""
16626
+ ] }),
16627
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Description, { children: "Are you sure you want to delete this version? This action cannot be undone." })
16628
+ ] }),
16629
+ /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Footer, { children: [
16630
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Cancel, { children: "Cancel" }),
16631
+ /* @__PURE__ */ jsxRuntime.jsx(
16632
+ AlertDialog.Action,
16633
+ {
16634
+ className: "bg-red-500 hover:bg-red-600",
16635
+ onClick: () => {
16636
+ if (versionToDelete !== null) {
16637
+ deleteVersion(versionToDelete);
16638
+ }
16639
+ },
16640
+ children: "Delete"
16641
+ }
16642
+ )
16643
+ ] })
16644
+ ] }) })
16645
+ ] });
16646
+ }
16647
+
16648
+ function AgentInformation({ agentId, threadId }) {
16649
+ const { data: agent, isLoading } = useAgent(agentId);
16650
+ const { data: modelProviders } = useModelProviders();
16651
+ const { mutateAsync: updateModel } = useUpdateAgentModel(agentId);
16652
+ const { mutate: reorderModelList } = useReorderModelList(agentId);
16653
+ const { mutateAsync: updateModelInModelList } = useUpdateModelInModelList(agentId);
16654
+ const { data: memory, isLoading: isMemoryLoading } = useMemory(agentId);
16655
+ const { settings, setSettings } = useAgentSettings();
16656
+ const STORAGE_KEY = "agent-info-selected-tab";
16657
+ const [selectedTab, setSelectedTab] = React.useState(() => {
16658
+ return sessionStorage.getItem(STORAGE_KEY) || "overview";
16659
+ });
16660
+ const handleTabChange = (value) => {
16661
+ setSelectedTab(value);
16662
+ sessionStorage.setItem(STORAGE_KEY, value);
16663
+ };
16664
+ React.useEffect(() => {
16665
+ if (agent?.modelId?.includes("gpt-5")) {
16666
+ setSettings({
16667
+ ...settings || {},
16668
+ modelSettings: {
16669
+ ...settings?.modelSettings || {},
16670
+ temperature: 1
16671
+ }
16672
+ });
16673
+ }
16674
+ }, [agent]);
16675
+ React.useEffect(() => {
16676
+ if (!isMemoryLoading && !memory?.result && selectedTab === "memory") {
16677
+ handleTabChange("overview");
16678
+ }
16679
+ }, [isMemoryLoading, memory?.result, selectedTab]);
16680
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-rows-[auto_1fr] h-full items-start overflow-y-auto border-l-sm border-border1", children: [
16681
+ /* @__PURE__ */ jsxRuntime.jsx(AgentEntityHeader, { agentId, isLoading: isMemoryLoading, agentName: agent?.name || "" }),
16682
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "overview", value: selectedTab, onValueChange: handleTabChange, children: [
16683
+ /* @__PURE__ */ jsxRuntime.jsxs(TabList$1, { children: [
16684
+ /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "overview", children: "Overview" }),
16685
+ /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "model-settings", children: "Model Settings" }),
16686
+ memory?.result && /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "memory", children: "Memory" })
16687
+ ] }),
16688
+ /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "overview", children: [
16689
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }),
16690
+ agent && /* @__PURE__ */ jsxRuntime.jsx(
16691
+ AgentMetadata,
16692
+ {
16693
+ agentId,
16694
+ agent,
16695
+ updateModel,
16696
+ updateModelInModelList,
16697
+ reorderModelList,
16698
+ modelProviders: modelProviders || [],
16699
+ hasMemoryEnabled: Boolean(memory?.result),
16700
+ promptSlot: /* @__PURE__ */ jsxRuntime.jsx(AgentPromptEnhancer, { agentId }),
16701
+ modelVersion: agent.modelVersion
16702
+ }
16703
+ )
16704
+ ] }),
16705
+ /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "model-settings", children: [
16706
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }),
16707
+ agent && /* @__PURE__ */ jsxRuntime.jsx(
16708
+ AgentSettings,
16709
+ {
16710
+ modelVersion: agent.modelVersion,
16711
+ hasMemory: Boolean(memory?.result),
16712
+ hasSubAgents: Boolean(Object.keys(agent.agents || {}).length > 0)
16713
+ }
16714
+ )
16715
+ ] }),
16716
+ /* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "memory", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }) : /* @__PURE__ */ jsxRuntime.jsx(AgentMemory, { agentId, threadId }) })
16717
+ ] }) })
16718
+ ] });
16719
+ }
16720
+
16721
+ const NameCell$1 = ({ row }) => {
16722
+ const { Link, paths } = useLinkComponent();
16723
+ const tool = row.original;
16724
+ return /* @__PURE__ */ jsxRuntime.jsx(
16725
+ EntryCell,
16726
+ {
16727
+ name: /* @__PURE__ */ jsxRuntime.jsx(Link, { className: "w-full space-y-0", href: paths.toolLink(tool.id), children: tool.id }),
16728
+ description: tool.description
16729
+ }
16730
+ );
16731
+ };
16732
+ const columns$1 = [
16733
+ {
16734
+ header: "Name",
16735
+ accessorKey: "name",
16736
+ cell: NameCell$1
16737
+ },
16738
+ {
16739
+ header: "Attached entities",
16740
+ accessorKey: "attachedEntities",
16741
+ cell: ({ row }) => {
16742
+ const tool = row.original;
16743
+ const agentsCount = tool.agents.length;
16744
+ return /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "default", icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, { className: "text-accent1" }), children: [
16745
+ agentsCount,
16746
+ " agent",
16747
+ agentsCount > 1 ? "s" : ""
16748
+ ] }) });
16749
+ }
16750
+ }
16751
+ ];
16752
+
16753
+ const prepareToolsTable = (tools, agents) => {
16754
+ const toolsWithAgents = /* @__PURE__ */ new Map();
16755
+ const agentsKeys = Object.keys(agents);
16756
+ for (const k of agentsKeys) {
16757
+ const agent = agents[k];
16758
+ const agentToolsDict = agent.tools;
16759
+ const agentToolsKeys = Object.keys(agentToolsDict);
16760
+ for (const key of agentToolsKeys) {
16761
+ const tool = agentToolsDict[key];
16762
+ if (!toolsWithAgents.has(tool.id)) {
16763
+ toolsWithAgents.set(tool.id, {
16764
+ ...tool,
16765
+ agents: []
16766
+ });
16767
+ }
16768
+ toolsWithAgents.get(tool.id).agents.push({ ...agent, id: k });
16769
+ }
16770
+ }
16771
+ for (const [_, tool] of Object.entries(tools)) {
16772
+ if (!toolsWithAgents.has(tool.id)) {
16773
+ toolsWithAgents.set(tool.id, {
16774
+ ...tool,
16775
+ agents: []
16776
+ });
16777
+ }
16778
+ }
16779
+ return Array.from(toolsWithAgents.values());
16780
+ };
16781
+
16782
+ function ToolTable({ tools, agents, isLoading }) {
16783
+ const [search, setSearch] = React.useState("");
16784
+ const { navigate, paths } = useLinkComponent();
16785
+ const toolData = React.useMemo(() => prepareToolsTable(tools, agents), [tools, agents]);
16786
+ const table = reactTable.useReactTable({
16787
+ data: toolData,
16788
+ columns: columns$1,
16789
+ getCoreRowModel: reactTable.getCoreRowModel()
16790
+ });
16791
+ const ths = table.getHeaderGroups()[0];
16792
+ const rows = table.getRowModel().rows.concat();
16793
+ if (rows.length === 0 && !isLoading) {
16794
+ return /* @__PURE__ */ jsxRuntime.jsx(EmptyToolsTable, {});
16795
+ }
16796
+ const filteredRows = rows.filter((row) => row.original.id.toLowerCase().includes(search.toLowerCase()));
16797
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
16798
+ /* @__PURE__ */ jsxRuntime.jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Searchbar, { onSearch: setSearch, label: "Search tools", placeholder: "Search tools" }) }),
16799
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ToolTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
16800
+ /* @__PURE__ */ jsxRuntime.jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: reactTable.flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
16801
+ /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: filteredRows.map((row) => {
16802
+ const firstAgent = row.original.agents[0];
16803
+ const link = firstAgent ? paths.agentToolLink(firstAgent.id, row.original.id) : paths.toolLink(row.original.id);
16804
+ return /* @__PURE__ */ jsxRuntime.jsx(Row, { onClick: () => navigate(link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id);
16805
+ }) })
16806
+ ] }) }) })
16807
+ ] });
16808
+ }
16809
+ const ToolTableSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
16810
+ /* @__PURE__ */ jsxRuntime.jsxs(Thead, { children: [
16811
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Name" }),
16812
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Used by" })
16813
+ ] }),
16814
+ /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs(Row, { children: [
16815
+ /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) }),
16816
+ /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) })
16817
+ ] }, index)) })
16818
+ ] });
16819
+ const EmptyToolsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
16820
+ EmptyState,
16821
+ {
16822
+ iconSlot: /* @__PURE__ */ jsxRuntime.jsx(ToolCoinIcon, {}),
16823
+ titleSlot: "Configure Tools",
16824
+ descriptionSlot: "Mastra tools are not configured yet. You can find more information in the documentation.",
16825
+ actionSlot: /* @__PURE__ */ jsxRuntime.jsxs(
16826
+ Button$1,
16827
+ {
16828
+ size: "lg",
16829
+ className: "w-full",
16830
+ variant: "light",
16831
+ as: "a",
16832
+ href: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
16833
+ target: "_blank",
16834
+ children: [
16835
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}) }),
16836
+ "Docs"
16837
+ ]
16838
+ }
16839
+ )
16840
+ }
16841
+ ) });
16842
+
16843
+ const useExecuteTool = () => {
16844
+ const client = react$3.useMastraClient();
16845
+ return reactQuery.useMutation({
16846
+ mutationFn: async ({
16847
+ toolId,
16848
+ input,
16849
+ runtimeContext: playgroundRuntimeContext
16850
+ }) => {
16851
+ const runtimeContext = new di.RuntimeContext();
16852
+ Object.entries(playgroundRuntimeContext ?? {}).forEach(([key, value]) => {
16853
+ runtimeContext.set(key, value);
16854
+ });
16855
+ try {
16856
+ const tool = client.getTool(toolId);
16857
+ const response = await tool.execute({ data: input, runtimeContext });
16858
+ return response;
16859
+ } catch (error) {
16860
+ sonner.toast.error("Error executing dev tool");
16861
+ console.error("Error executing dev tool:", error);
16862
+ throw error;
16863
+ }
16864
+ }
16865
+ });
16866
+ };
16867
+
16868
+ const useTools = () => {
16869
+ const { runtimeContext } = usePlaygroundStore();
16870
+ const client = react$3.useMastraClient();
16871
+ return reactQuery.useQuery({
16872
+ queryKey: ["tools"],
16873
+ queryFn: () => client.getTools(runtimeContext)
16874
+ });
16875
+ };
16876
+ const useTool = (toolId) => {
16877
+ const client = react$3.useMastraClient();
16878
+ const { runtimeContext } = usePlaygroundStore();
16879
+ return reactQuery.useQuery({
16880
+ queryKey: ["tool", toolId],
16881
+ queryFn: () => client.getTool(toolId).details(runtimeContext)
16882
+ });
16883
+ };
16884
+
16885
+ const ToolPanel = ({ toolId }) => {
16886
+ const { data: tool, isLoading } = useTool(toolId);
16887
+ const { mutateAsync: executeTool, isPending: isExecuting, data: result } = useExecuteTool();
16888
+ const { runtimeContext: playgroundRuntimeContext } = usePlaygroundStore();
16889
+ const handleExecuteTool = async (data) => {
16890
+ if (!tool) return;
16891
+ return executeTool({
16892
+ toolId: tool.id,
16893
+ input: data,
16894
+ runtimeContext: playgroundRuntimeContext
16895
+ });
16896
+ };
16897
+ const zodInputSchema = tool?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(superjson.parse(tool?.inputSchema))) : z.z.object({});
16898
+ if (isLoading) return null;
16899
+ if (!tool)
16900
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center px-6", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", className: "text-icon3", children: "Tool not found" }) });
16901
+ return /* @__PURE__ */ jsxRuntime.jsx(
16902
+ ToolExecutor,
16903
+ {
16904
+ executionResult: result,
16905
+ isExecutingTool: isExecuting,
16906
+ zodInputSchema,
16907
+ handleExecuteTool,
16908
+ toolDescription: tool.description,
16909
+ toolId: tool.id
16910
+ }
16911
+ );
16912
+ };
16913
+
16914
+ function TemplatesTools({
16915
+ tagOptions,
16916
+ selectedTag,
16917
+ providerOptions,
16918
+ selectedProvider,
16919
+ onTagChange,
16920
+ onProviderChange,
16921
+ searchTerm,
16922
+ onSearchChange,
16923
+ onReset,
16924
+ className,
16925
+ isLoading
16926
+ }) {
16927
+ if (isLoading) {
16928
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16929
+ "div",
16930
+ {
16931
+ className: cn(
16932
+ "h-[6.5rem] flex items-center gap-[2rem]",
16933
+ "[&>div]:bg-surface3 [&>div]:w-[12rem] [&>div]:h-[2rem] [&>div]:animate-pulse",
16934
+ className
16935
+ ),
16936
+ children: [
16937
+ /* @__PURE__ */ jsxRuntime.jsx("div", {}),
16938
+ " ",
16939
+ /* @__PURE__ */ jsxRuntime.jsx("div", {}),
16940
+ " ",
16941
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
16942
+ ]
16943
+ }
16944
+ );
16945
+ }
16946
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap mx-auto sticky top-0 gap-[2rem] bg-surface2 py-[2rem]", className), children: [
16947
+ /* @__PURE__ */ jsxRuntime.jsx(
16948
+ SearchField,
16949
+ {
16950
+ label: "Search templates",
16951
+ value: searchTerm,
16952
+ onChange: (e) => onSearchChange?.(e.target.value),
16953
+ placeholder: "Search Template"
16954
+ }
16955
+ ),
16956
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Filter by tag", value: selectedTag, onValueChange: onTagChange, options: tagOptions }),
16957
+ /* @__PURE__ */ jsxRuntime.jsx(
16958
+ SelectField,
16959
+ {
16960
+ label: "Filter by provider",
16961
+ value: selectedProvider,
16962
+ onValueChange: onProviderChange,
16963
+ options: providerOptions
16964
+ }
16965
+ ),
16966
+ onReset && /* @__PURE__ */ jsxRuntime.jsxs(Button, { onClick: onReset, children: [
16967
+ "Reset ",
16968
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {})
16969
+ ] })
16970
+ ] });
16971
+ }
16972
+
16973
+ function getRepoName(githubUrl) {
16974
+ return githubUrl.replace(/\/$/, "").split("/").pop();
16975
+ }
16976
+ function Container({ children, className }) {
16977
+ return /* @__PURE__ */ jsxRuntime.jsx(
16978
+ "div",
16979
+ {
16980
+ className: cn(
16981
+ "border border-border1 rounded-lg mt-[3rem] py-[2rem] lg:min-h-[25rem] transition-height px-[1rem] lg:px-[3rem]",
16982
+ className
16983
+ ),
16984
+ children
16985
+ }
16986
+ );
16987
+ }
16988
+
16989
+ function TemplatesList({ templates, linkComponent, className, isLoading }) {
16990
+ const LinkComponent = linkComponent || "a";
16991
+ if (isLoading) {
16992
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[4rem] bg-surface3 animate-pulse rounded-lg" }, index)) });
16993
+ }
16994
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: templates.map((template) => {
16995
+ const hasMetaInfo = template?.agents || template?.tools || template?.networks || template?.workflows || template?.mcp;
16996
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16997
+ "article",
16998
+ {
16999
+ className: cn(
17000
+ "border border-border1 rounded-lg overflow-hidden w-full grid grid-cols-[1fr_auto] bg-surface3 transition-colors hover:bg-surface4"
17001
+ ),
17002
+ children: [
17003
+ /* @__PURE__ */ jsxRuntime.jsxs(
17004
+ LinkComponent,
17005
+ {
17006
+ to: `/templates/${template.slug}`,
17007
+ className: cn("grid [&:hover_p]:text-icon5", {
17008
+ "grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
17009
+ }),
17010
+ children: [
17011
+ template.imageURL && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-hidden"), children: /* @__PURE__ */ jsxRuntime.jsx(
17012
+ "div",
17013
+ {
17014
+ className: "w-full h-full bg-cover thumb transition-scale duration-150",
17015
+ style: {
17016
+ backgroundImage: `url(${template.imageURL})`
17017
+ }
17018
+ }
17019
+ ) }),
17020
+ /* @__PURE__ */ jsxRuntime.jsxs(
17021
+ "div",
17022
+ {
17023
+ className: cn(
17024
+ "grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
17025
+ "[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
17026
+ ),
17027
+ children: [
17028
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
17029
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
17030
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
17031
+ hasMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
17032
+ "ul",
17033
+ {
17034
+ className: cn(
17035
+ "flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
17036
+ "[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
17037
+ ),
17038
+ children: [
17039
+ template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
17040
+ /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}),
17041
+ " ",
17042
+ template.agents.length
17043
+ ] }),
17044
+ template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
17045
+ /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}),
17046
+ " ",
17047
+ template.tools.length
17048
+ ] }),
17049
+ template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
17050
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.NetworkIcon, {}),
17051
+ " ",
17052
+ template.networks.length
17053
+ ] }),
17054
+ template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
17055
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.WorkflowIcon, {}),
17056
+ " ",
17057
+ template.workflows.length
17058
+ ] }),
17059
+ template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
17060
+ /* @__PURE__ */ jsxRuntime.jsx(McpServerIcon, {}),
17061
+ " ",
17062
+ template.mcp.length
17063
+ ] })
17064
+ ]
17065
+ }
17066
+ ),
17067
+ hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsxRuntime.jsx("small", { children: "|" }),
17068
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "", children: provider }, provider)) })
17069
+ ] })
17070
+ ]
17071
+ }
17072
+ )
17073
+ ]
17074
+ }
17075
+ ),
17076
+ /* @__PURE__ */ jsxRuntime.jsx(
17077
+ "a",
17078
+ {
17079
+ href: template.githubUrl,
17080
+ className: cn("group items-center gap-[0.5rem] text-[0.875rem] ml-auto pr-[1rem] hidden", "lg:flex"),
17081
+ target: "_blank",
17082
+ rel: "noopener noreferrer",
17083
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-[0.5rem] px-[0.5rem] py-[0.25rem] rounded bg-surface1 group-hover:bg-surface2 text-icon3 transition-colors group-hover:text-icon5 ", children: [
17084
+ /* @__PURE__ */ jsxRuntime.jsx(GithubIcon, {}),
17085
+ " ",
17086
+ getRepoName(template.githubUrl)
17087
+ ] })
17088
+ }
17089
+ )
17090
+ ]
17091
+ },
17092
+ template.slug
17093
+ );
17094
+ }) });
17095
+ }
17096
+
17097
+ function TemplateInfo({
17098
+ title,
17099
+ description,
17100
+ imageURL,
17101
+ githubUrl,
17102
+ isLoading,
17103
+ infoData,
17104
+ templateSlug
17105
+ }) {
17106
+ const branchName = templateSlug ? `feat/install-template-${templateSlug}` : "feat/install-template-[slug]";
17107
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17108
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid mt-[2rem] items-center"), children: /* @__PURE__ */ jsxRuntime.jsxs(
17109
+ "div",
17110
+ {
17111
+ className: cn(
17112
+ "text-[1.5rem] flex items-center gap-[0.75rem]",
17113
+ "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
17114
+ {
17115
+ "[&>svg]:opacity-20": isLoading
17116
+ }
17117
+ ),
17118
+ children: [
17119
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, {}),
17120
+ /* @__PURE__ */ jsxRuntime.jsx(
17121
+ "h2",
17122
+ {
17123
+ className: cn({
17124
+ "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
17125
+ }),
17126
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : title
17127
+ }
17128
+ )
17129
+ ]
17130
+ }
17131
+ ) }),
17132
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] ", children: [
17133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid", children: [
17134
+ /* @__PURE__ */ jsxRuntime.jsx(
17135
+ "p",
17136
+ {
17137
+ className: cn("mb-[1rem] text-[0.875rem] text-icon4 mt-[.5rem] leading-[1.75]", {
17138
+ "bg-surface4 rounded-lg ": isLoading
17139
+ }),
17140
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: " " }) : description
17141
+ }
17142
+ ),
17143
+ !isLoading && templateSlug && /* @__PURE__ */ jsxRuntime.jsxs(
17144
+ "div",
17145
+ {
17146
+ className: cn(
17147
+ "bg-surface2 border border-surface4 rounded-lg p-[1rem] mb-[1rem]",
17148
+ "flex items-start gap-[0.75rem]"
17149
+ ),
17150
+ children: [
17151
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-[0.125rem]", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, { className: "w-[1.1em] h-[1.1em] text-blue-500" }) }),
17152
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-[0.5rem]", children: [
17153
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[0.5rem]", children: [
17154
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranchIcon, { className: "w-[1em] h-[1em] text-icon4" }),
17155
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] font-medium text-icon5", children: "A new Git branch will be created" })
17156
+ ] }),
17157
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[0.8125rem] text-icon4 space-y-[0.25rem]", children: [
17158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17159
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Branch name:" }),
17160
+ " ",
17161
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "bg-surface3 px-[0.375rem] py-[0.125rem] rounded text-[0.75rem] font-mono", children: branchName })
17162
+ ] }),
17163
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "This ensures safe installation with easy rollback if needed. Your main branch remains unchanged." })
17164
+ ] })
17165
+ ] })
17166
+ ]
17167
+ }
17168
+ ),
17169
+ githubUrl && /* @__PURE__ */ jsxRuntime.jsxs(
17170
+ "a",
17171
+ {
17172
+ href: githubUrl,
17173
+ target: "_blank",
17174
+ rel: "noopener noreferrer",
17175
+ className: "flex items-center gap-[.5rem] mt-auto text-icon3 text-[0.875rem] hover:text-icon5",
17176
+ children: [
17177
+ /* @__PURE__ */ jsxRuntime.jsx(GithubIcon, {}),
17178
+ githubUrl?.split("/")?.pop()
17179
+ ]
17180
+ }
17181
+ )
17182
+ ] }),
17183
+ infoData && /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: infoData, LinkComponent: lucideReact.Link, labelsAreHidden: true, isLoading })
17184
+ ] })
17185
+ ] });
17186
+ }
17187
+
17188
+ function TemplateForm({
17189
+ providerOptions,
17190
+ selectedProvider,
17191
+ onProviderChange,
17192
+ variables,
17193
+ errors,
17194
+ handleInstallTemplate,
17195
+ handleVariableChange,
17196
+ isLoadingEnvVars,
17197
+ defaultModelProvider,
17198
+ defaultModelId,
17199
+ onModelUpdate
17200
+ }) {
17201
+ return /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-[40rem] my-[1rem] p-[1rem] lg:p-[2rem] mx-auto gap-[2rem] grid", children: [
17202
+ /* @__PURE__ */ jsxRuntime.jsxs(
17203
+ "h2",
17204
+ {
17205
+ className: cn(
17206
+ "text-icon4 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
17207
+ "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
17208
+ ),
17209
+ children: [
17210
+ "Install Template ",
17211
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageOpenIcon, {})
17212
+ ]
17213
+ }
17214
+ ),
17215
+ /* @__PURE__ */ jsxRuntime.jsx(
17216
+ SelectField,
17217
+ {
17218
+ options: providerOptions,
17219
+ label: "Template AI Model Provider",
17220
+ onValueChange: onProviderChange,
17221
+ value: selectedProvider,
17222
+ placeholder: "Select"
17223
+ }
17224
+ ),
17225
+ selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17226
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
17227
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxRuntime.jsxs(
17228
+ "div",
17229
+ {
17230
+ className: cn(
17231
+ "flex items-center justify-center col-span-2 text-icon3 text-[0.75rem] gap-[1rem]",
17232
+ "[&_svg]:opacity-50 [&_svg]:w-[1.1em] [&_svg]:h-[1.1em]",
17233
+ "animate-in fade-in duration-300"
17234
+ ),
17235
+ children: [
17236
+ /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}),
17237
+ " Loading variables..."
17238
+ ]
17239
+ }
17240
+ ) : Object.entries(variables).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
17241
+ /* @__PURE__ */ jsxRuntime.jsx(
17242
+ InputField,
17243
+ {
17244
+ name: `env-${key}`,
17245
+ labelIsHidden: true,
17246
+ label: "Key",
17247
+ value: key,
17248
+ disabled: true,
17249
+ className: "w-full"
17250
+ }
17251
+ ),
17252
+ /* @__PURE__ */ jsxRuntime.jsx(
17253
+ InputField,
17254
+ {
17255
+ name: key,
15371
17256
  labelIsHidden: true,
15372
17257
  label: "Value",
15373
17258
  value,
@@ -17859,535 +19744,172 @@ const DarkLogo = (props) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "100
17859
19744
  d: "M59.2351 43.2352L43.194 59.2763L40.958 57.0403L56.9991 40.9992L59.2351 43.2352Z",
17860
19745
  fill: "currentColor"
17861
19746
  }
17862
- ),
17863
- /* @__PURE__ */ jsxRuntime.jsx(
17864
- "path",
17865
- {
17866
- fillRule: "evenodd",
17867
- clipRule: "evenodd",
17868
- d: "M43.1969 40.9992L59.2379 57.0403L57.002 59.2763L40.9609 43.2352L43.1969 40.9992Z",
17869
- fill: "currentColor"
17870
- }
17871
- ),
17872
- /* @__PURE__ */ jsxRuntime.jsx(
17873
- "path",
17874
- {
17875
- fillRule: "evenodd",
17876
- clipRule: "evenodd",
17877
- d: "M23.7151 33.0924C17.0466 37.565 13.1629 43.573 13.1629 49.9999C13.1629 56.4269 17.0466 62.4349 23.7151 66.9075C30.3734 71.3733 39.662 74.1867 50.0004 74.1867C60.3388 74.1867 69.6274 71.3733 76.2857 66.9075C82.9541 62.4349 86.8378 56.4269 86.8378 49.9999C86.8378 43.573 82.9541 37.565 76.2857 33.0924C69.6274 28.6266 60.3388 25.8132 50.0004 25.8132C39.662 25.8132 30.3734 28.6266 23.7151 33.0924ZM21.9537 30.4662C29.2002 25.6059 39.1209 22.651 50.0004 22.651C60.8799 22.651 70.8006 25.6059 78.0471 30.4662C85.2834 35.3197 90 42.1957 90 49.9999C90 57.8042 85.2834 64.6802 78.0471 69.5337C70.8006 74.394 60.8799 77.3489 50.0004 77.3489C39.1209 77.3489 29.2002 74.394 21.9537 69.5337C14.7174 64.6802 10.0008 57.8042 10.0008 49.9999C10.0008 42.1957 14.7174 35.3197 21.9537 30.4662Z",
17878
- fill: "currentColor"
17879
- }
17880
- )
17881
- ] });
17882
-
17883
- const Entity = ({ children, className, onClick }) => {
17884
- return /* @__PURE__ */ jsxRuntime.jsx(
17885
- "div",
17886
- {
17887
- tabIndex: onClick ? 0 : void 0,
17888
- onKeyDown: (e) => {
17889
- if (!onClick) return;
17890
- if (e.key === "Enter" || e.key === " ") {
17891
- e.preventDefault();
17892
- onClick?.();
17893
- }
17894
- },
17895
- className: clsx(
17896
- "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
17897
- onClick && "cursor-pointer hover:bg-surface4 transition-all",
17898
- className
17899
- ),
17900
- onClick,
17901
- children
17902
- }
17903
- );
17904
- };
17905
- const EntityIcon = ({ children, className }) => {
17906
- return /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
17907
- };
17908
- const EntityName = ({ children, className }) => {
17909
- return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
17910
- };
17911
- const EntityDescription = ({ children, className }) => {
17912
- return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
17913
- };
17914
- const EntityContent = ({ children, className }) => {
17915
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
17916
- };
17917
-
17918
- function usePolling({
17919
- fetchFn,
17920
- interval = 3e3,
17921
- enabled = false,
17922
- onSuccess,
17923
- onError,
17924
- shouldContinue = () => true,
17925
- restartPolling = false
17926
- }) {
17927
- const [isPolling, setIsPolling] = React.useState(enabled);
17928
- const [error, setError] = React.useState(null);
17929
- const [data, setData] = React.useState(null);
17930
- const [isLoading, setIsLoading] = React.useState(false);
17931
- const [firstCallLoading, setFirstCallLoading] = React.useState(false);
17932
- const timeoutRef = React.useRef(null);
17933
- const mountedRef = React.useRef(true);
17934
- const [restart, setRestart] = React.useState(restartPolling);
17935
- const cleanup = React.useCallback(() => {
17936
- console.log("cleanup");
17937
- if (timeoutRef.current) {
17938
- clearTimeout(timeoutRef.current);
17939
- timeoutRef.current = null;
17940
- }
17941
- }, []);
17942
- const stopPolling = React.useCallback(() => {
17943
- console.log("stopPolling");
17944
- setIsPolling(false);
17945
- cleanup();
17946
- }, [cleanup]);
17947
- const startPolling = React.useCallback(() => {
17948
- console.log("startPolling");
17949
- setIsPolling(true);
17950
- setError(null);
17951
- }, []);
17952
- const executePoll = React.useCallback(
17953
- async (refetch2 = true) => {
17954
- if (!mountedRef.current) return;
17955
- setIsLoading(true);
17956
- try {
17957
- const result = await fetchFn();
17958
- setData(result);
17959
- setError(null);
17960
- onSuccess?.(result);
17961
- if (shouldContinue(result) && refetch2) {
17962
- timeoutRef.current = setTimeout(executePoll, interval);
17963
- } else {
17964
- stopPolling();
17965
- }
17966
- } catch (err) {
17967
- if (!mountedRef.current) return;
17968
- setError(err);
17969
- onError?.(err);
17970
- stopPolling();
17971
- } finally {
17972
- if (mountedRef.current) {
17973
- setFirstCallLoading(false);
17974
- setIsLoading(false);
17975
- }
17976
- }
17977
- },
17978
- [fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
17979
- );
17980
- const refetch = React.useCallback(
17981
- (withPolling = false) => {
17982
- console.log("refetch", { withPolling });
17983
- if (withPolling) {
17984
- setIsPolling(true);
17985
- } else {
17986
- executePoll(false);
17987
- }
17988
- setError(null);
17989
- },
17990
- [executePoll]
17991
- );
17992
- React.useEffect(() => {
17993
- mountedRef.current = true;
17994
- if (enabled && isPolling) {
17995
- executePoll(true);
17996
- }
17997
- return () => {
17998
- console.log("cleanup poll");
17999
- mountedRef.current = false;
18000
- cleanup();
18001
- };
18002
- }, [enabled, isPolling, executePoll, cleanup]);
18003
- React.useEffect(() => {
18004
- setRestart(restartPolling);
18005
- }, [restartPolling]);
18006
- React.useEffect(() => {
18007
- if (restart && !isPolling) {
18008
- setIsPolling(true);
18009
- executePoll();
18010
- setRestart(false);
18011
- }
18012
- }, [restart]);
18013
- return {
18014
- isPolling,
18015
- isLoading,
18016
- error,
18017
- data,
18018
- startPolling,
18019
- stopPolling,
18020
- firstCallLoading,
18021
- refetch
18022
- };
18023
- }
18024
-
18025
- const PlaygroundQueryClient = ({ children }) => {
18026
- const queryClient = new reactQuery.QueryClient();
18027
- return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });
18028
- };
18029
-
18030
- const useMemory = (agentId) => {
18031
- const client = react$3.useMastraClient();
18032
- return reactQuery.useQuery({
18033
- queryKey: ["memory", agentId],
18034
- queryFn: () => agentId ? client.getMemoryStatus(agentId) : null,
18035
- enabled: Boolean(agentId),
18036
- staleTime: 5 * 60 * 1e3,
18037
- // 5 minutes
18038
- gcTime: 10 * 60 * 1e3,
18039
- // 10 minutes
18040
- retry: false
18041
- });
18042
- };
18043
- const useMemoryConfig = (agentId) => {
18044
- const client = react$3.useMastraClient();
18045
- return reactQuery.useQuery({
18046
- queryKey: ["memory", "config", agentId],
18047
- queryFn: () => agentId ? client.getMemoryConfig({ agentId }) : null,
18048
- enabled: Boolean(agentId),
18049
- staleTime: 5 * 60 * 1e3,
18050
- // 5 minutes
18051
- gcTime: 10 * 60 * 1e3,
18052
- // 10 minutes
18053
- retry: false,
18054
- refetchOnWindowFocus: false
18055
- });
18056
- };
18057
- const useThreads = ({
18058
- resourceId,
18059
- agentId,
18060
- isMemoryEnabled
18061
- }) => {
18062
- const client = react$3.useMastraClient();
18063
- return reactQuery.useQuery({
18064
- queryKey: ["memory", "threads", resourceId, agentId],
18065
- queryFn: () => isMemoryEnabled ? client.getMemoryThreads({ resourceId, agentId }) : null,
18066
- enabled: Boolean(isMemoryEnabled),
18067
- staleTime: 0,
18068
- gcTime: 0,
18069
- retry: false,
18070
- refetchOnWindowFocus: false
18071
- });
18072
- };
18073
- const useDeleteThread = () => {
18074
- const client = react$3.useMastraClient();
18075
- const queryClient = reactQuery.useQueryClient();
18076
- return reactQuery.useMutation({
18077
- mutationFn: ({ threadId, agentId, networkId }) => client.deleteThread(threadId, { agentId, networkId }),
18078
- onSuccess: (_, variables) => {
18079
- const { agentId, networkId } = variables;
18080
- if (agentId) {
18081
- queryClient.invalidateQueries({ queryKey: ["memory", "threads", agentId, agentId] });
18082
- }
18083
- if (networkId) {
18084
- queryClient.invalidateQueries({ queryKey: ["network", "threads", networkId, networkId] });
18085
- }
18086
- sonner.toast.success("Chat deleted successfully");
18087
- },
18088
- onError: () => {
18089
- sonner.toast.error("Failed to delete chat");
18090
- }
18091
- });
18092
- };
18093
- const useMemorySearch = ({
18094
- agentId,
18095
- resourceId,
18096
- threadId
18097
- }) => {
18098
- const searchMemory = async (searchQuery, memoryConfig) => {
18099
- if (!searchQuery.trim()) {
18100
- return { results: [], count: 0, query: searchQuery };
18101
- }
18102
- const params = new URLSearchParams({
18103
- searchQuery,
18104
- resourceId,
18105
- agentId
18106
- });
18107
- if (threadId) {
18108
- params.append("threadId", threadId);
18109
- }
18110
- if (memoryConfig) {
18111
- params.append("memoryConfig", JSON.stringify(memoryConfig));
19747
+ ),
19748
+ /* @__PURE__ */ jsxRuntime.jsx(
19749
+ "path",
19750
+ {
19751
+ fillRule: "evenodd",
19752
+ clipRule: "evenodd",
19753
+ d: "M43.1969 40.9992L59.2379 57.0403L57.002 59.2763L40.9609 43.2352L43.1969 40.9992Z",
19754
+ fill: "currentColor"
18112
19755
  }
18113
- const response = await fetch(`/api/memory/search?${params}`, {
18114
- method: "GET",
18115
- headers: {
18116
- "Content-Type": "application/json",
18117
- "x-mastra-dev-playground": "true"
18118
- }
18119
- });
18120
- if (!response.ok) {
18121
- const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
18122
- console.error("Search memory error:", errorData);
18123
- throw new Error(errorData.message || errorData.error || "Failed to search memory");
19756
+ ),
19757
+ /* @__PURE__ */ jsxRuntime.jsx(
19758
+ "path",
19759
+ {
19760
+ fillRule: "evenodd",
19761
+ clipRule: "evenodd",
19762
+ d: "M23.7151 33.0924C17.0466 37.565 13.1629 43.573 13.1629 49.9999C13.1629 56.4269 17.0466 62.4349 23.7151 66.9075C30.3734 71.3733 39.662 74.1867 50.0004 74.1867C60.3388 74.1867 69.6274 71.3733 76.2857 66.9075C82.9541 62.4349 86.8378 56.4269 86.8378 49.9999C86.8378 43.573 82.9541 37.565 76.2857 33.0924C69.6274 28.6266 60.3388 25.8132 50.0004 25.8132C39.662 25.8132 30.3734 28.6266 23.7151 33.0924ZM21.9537 30.4662C29.2002 25.6059 39.1209 22.651 50.0004 22.651C60.8799 22.651 70.8006 25.6059 78.0471 30.4662C85.2834 35.3197 90 42.1957 90 49.9999C90 57.8042 85.2834 64.6802 78.0471 69.5337C70.8006 74.394 60.8799 77.3489 50.0004 77.3489C39.1209 77.3489 29.2002 74.394 21.9537 69.5337C14.7174 64.6802 10.0008 57.8042 10.0008 49.9999C10.0008 42.1957 14.7174 35.3197 21.9537 30.4662Z",
19763
+ fill: "currentColor"
18124
19764
  }
18125
- return response.json();
18126
- };
18127
- return { searchMemory };
18128
- };
19765
+ )
19766
+ ] });
18129
19767
 
18130
- const formatRelativeTime = (date) => {
18131
- const now = /* @__PURE__ */ new Date();
18132
- const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
18133
- if (seconds < 60) return "just now";
18134
- if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
18135
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
18136
- if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
18137
- return date.toLocaleDateString();
18138
- };
18139
- const MemorySearch = ({
18140
- searchMemory,
18141
- onResultClick,
18142
- className,
18143
- currentThreadId,
18144
- chatInputValue
18145
- }) => {
18146
- const [query, setQuery] = React.useState("");
18147
- const [results, setResults] = React.useState([]);
18148
- const [isSearching, setIsSearching] = React.useState(false);
18149
- const [isOpen, setIsOpen] = React.useState(false);
18150
- const [error, setError] = React.useState(null);
18151
- const searchTimeoutRef = React.useRef(void 0);
18152
- const dropdownRef = React.useRef(null);
18153
- const prevThreadIdRef = React.useRef(currentThreadId);
18154
- const lastSearchTimeRef = React.useRef(0);
18155
- const pendingSearchRef = React.useRef(null);
18156
- const handleSearch = React.useCallback(
18157
- async (searchQuery) => {
18158
- if (!searchQuery.trim()) {
18159
- setError(null);
18160
- return;
18161
- }
18162
- setIsSearching(true);
18163
- setError(null);
18164
- try {
18165
- const response = await searchMemory(searchQuery);
18166
- setResults(response.results);
18167
- setIsOpen((prev) => prev || response.results.length > 0);
18168
- } catch (err) {
18169
- setError("Failed to search memory");
18170
- console.error("Memory search error:", err);
18171
- } finally {
18172
- setIsSearching(false);
18173
- }
18174
- },
18175
- [searchMemory]
18176
- );
18177
- const handleInputChange = React.useCallback(
18178
- (e) => {
18179
- const value = e.target.value;
18180
- setQuery(value);
18181
- if (searchTimeoutRef.current) {
18182
- clearTimeout(searchTimeoutRef.current);
18183
- }
18184
- if (value.trim()) {
18185
- const now = Date.now();
18186
- const timeSinceLastSearch = now - lastSearchTimeRef.current;
18187
- if (timeSinceLastSearch >= 500) {
18188
- setIsSearching(true);
18189
- handleSearch(value);
18190
- lastSearchTimeRef.current = now;
18191
- } else {
18192
- setIsSearching(true);
18193
- pendingSearchRef.current = value;
18194
- const remainingTime = 500 - timeSinceLastSearch;
18195
- searchTimeoutRef.current = setTimeout(() => {
18196
- if (pendingSearchRef.current) {
18197
- handleSearch(pendingSearchRef.current);
18198
- lastSearchTimeRef.current = Date.now();
18199
- pendingSearchRef.current = null;
18200
- }
18201
- }, remainingTime);
18202
- }
18203
- } else {
18204
- setResults([]);
18205
- setIsOpen(false);
18206
- setIsSearching(false);
18207
- pendingSearchRef.current = null;
18208
- }
18209
- },
18210
- [handleSearch]
18211
- );
18212
- const handleKeyDown = React.useCallback(
18213
- (e) => {
18214
- if (e.key === "Enter") {
18215
- e.preventDefault();
18216
- if (searchTimeoutRef.current) {
18217
- clearTimeout(searchTimeoutRef.current);
19768
+ const Entity = ({ children, className, onClick }) => {
19769
+ return /* @__PURE__ */ jsxRuntime.jsx(
19770
+ "div",
19771
+ {
19772
+ tabIndex: onClick ? 0 : void 0,
19773
+ onKeyDown: (e) => {
19774
+ if (!onClick) return;
19775
+ if (e.key === "Enter" || e.key === " ") {
19776
+ e.preventDefault();
19777
+ onClick?.();
18218
19778
  }
18219
- handleSearch(query);
18220
- }
18221
- },
18222
- [query, handleSearch]
19779
+ },
19780
+ className: clsx(
19781
+ "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
19782
+ onClick && "cursor-pointer hover:bg-surface4 transition-all",
19783
+ className
19784
+ ),
19785
+ onClick,
19786
+ children
19787
+ }
18223
19788
  );
18224
- React.useEffect(() => {
18225
- return () => {
18226
- if (searchTimeoutRef.current) {
18227
- clearTimeout(searchTimeoutRef.current);
18228
- }
18229
- };
19789
+ };
19790
+ const EntityIcon = ({ children, className }) => {
19791
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
19792
+ };
19793
+ const EntityName = ({ children, className }) => {
19794
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
19795
+ };
19796
+ const EntityDescription = ({ children, className }) => {
19797
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
19798
+ };
19799
+ const EntityContent = ({ children, className }) => {
19800
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
19801
+ };
19802
+
19803
+ function usePolling({
19804
+ fetchFn,
19805
+ interval = 3e3,
19806
+ enabled = false,
19807
+ onSuccess,
19808
+ onError,
19809
+ shouldContinue = () => true,
19810
+ restartPolling = false
19811
+ }) {
19812
+ const [isPolling, setIsPolling] = React.useState(enabled);
19813
+ const [error, setError] = React.useState(null);
19814
+ const [data, setData] = React.useState(null);
19815
+ const [isLoading, setIsLoading] = React.useState(false);
19816
+ const [firstCallLoading, setFirstCallLoading] = React.useState(false);
19817
+ const timeoutRef = React.useRef(null);
19818
+ const mountedRef = React.useRef(true);
19819
+ const [restart, setRestart] = React.useState(restartPolling);
19820
+ const cleanup = React.useCallback(() => {
19821
+ console.log("cleanup");
19822
+ if (timeoutRef.current) {
19823
+ clearTimeout(timeoutRef.current);
19824
+ timeoutRef.current = null;
19825
+ }
18230
19826
  }, []);
18231
- React.useEffect(() => {
18232
- const handleClickOutside = (event) => {
18233
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
18234
- setIsOpen(false);
18235
- }
18236
- };
18237
- document.addEventListener("mousedown", handleClickOutside);
18238
- return () => document.removeEventListener("mousedown", handleClickOutside);
19827
+ const stopPolling = React.useCallback(() => {
19828
+ console.log("stopPolling");
19829
+ setIsPolling(false);
19830
+ cleanup();
19831
+ }, [cleanup]);
19832
+ const startPolling = React.useCallback(() => {
19833
+ console.log("startPolling");
19834
+ setIsPolling(true);
19835
+ setError(null);
18239
19836
  }, []);
18240
- React.useEffect(() => {
18241
- if (prevThreadIdRef.current !== currentThreadId && query.trim()) {
18242
- handleSearch(query);
18243
- }
18244
- prevThreadIdRef.current = currentThreadId;
18245
- }, [currentThreadId, query, handleSearch]);
18246
- React.useEffect(() => {
18247
- if (chatInputValue !== void 0 && chatInputValue !== query) {
18248
- setQuery(chatInputValue);
18249
- if (searchTimeoutRef.current) {
18250
- clearTimeout(searchTimeoutRef.current);
18251
- }
18252
- if (chatInputValue.trim()) {
18253
- const now = Date.now();
18254
- const timeSinceLastSearch = now - lastSearchTimeRef.current;
18255
- if (timeSinceLastSearch >= 500) {
18256
- setIsSearching(true);
18257
- handleSearch(chatInputValue);
18258
- lastSearchTimeRef.current = now;
19837
+ const executePoll = React.useCallback(
19838
+ async (refetch2 = true) => {
19839
+ if (!mountedRef.current) return;
19840
+ setIsLoading(true);
19841
+ try {
19842
+ const result = await fetchFn();
19843
+ setData(result);
19844
+ setError(null);
19845
+ onSuccess?.(result);
19846
+ if (shouldContinue(result) && refetch2) {
19847
+ timeoutRef.current = setTimeout(executePoll, interval);
18259
19848
  } else {
18260
- setIsSearching(true);
18261
- pendingSearchRef.current = chatInputValue;
18262
- const remainingTime = 500 - timeSinceLastSearch;
18263
- searchTimeoutRef.current = setTimeout(() => {
18264
- if (pendingSearchRef.current) {
18265
- handleSearch(pendingSearchRef.current);
18266
- lastSearchTimeRef.current = Date.now();
18267
- pendingSearchRef.current = null;
18268
- }
18269
- }, remainingTime);
19849
+ stopPolling();
19850
+ }
19851
+ } catch (err) {
19852
+ if (!mountedRef.current) return;
19853
+ setError(err);
19854
+ onError?.(err);
19855
+ stopPolling();
19856
+ } finally {
19857
+ if (mountedRef.current) {
19858
+ setFirstCallLoading(false);
19859
+ setIsLoading(false);
18270
19860
  }
19861
+ }
19862
+ },
19863
+ [fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
19864
+ );
19865
+ const refetch = React.useCallback(
19866
+ (withPolling = false) => {
19867
+ console.log("refetch", { withPolling });
19868
+ if (withPolling) {
19869
+ setIsPolling(true);
18271
19870
  } else {
18272
- setResults([]);
18273
- setIsOpen(false);
18274
- setIsSearching(false);
18275
- pendingSearchRef.current = null;
19871
+ executePoll(false);
18276
19872
  }
19873
+ setError(null);
19874
+ },
19875
+ [executePoll]
19876
+ );
19877
+ React.useEffect(() => {
19878
+ mountedRef.current = true;
19879
+ if (enabled && isPolling) {
19880
+ executePoll(true);
18277
19881
  }
18278
19882
  return () => {
18279
- if (searchTimeoutRef.current) {
18280
- clearTimeout(searchTimeoutRef.current);
18281
- }
19883
+ console.log("cleanup poll");
19884
+ mountedRef.current = false;
19885
+ cleanup();
18282
19886
  };
18283
- }, [chatInputValue]);
18284
- const handleResultClick = (messageId, threadId) => {
18285
- onResultClick?.(messageId, threadId);
18286
- };
18287
- const clearSearch = () => {
18288
- setQuery("");
18289
- setResults([]);
18290
- setIsOpen(false);
18291
- setError(null);
18292
- if (searchTimeoutRef.current) {
18293
- clearTimeout(searchTimeoutRef.current);
19887
+ }, [enabled, isPolling, executePoll, cleanup]);
19888
+ React.useEffect(() => {
19889
+ setRestart(restartPolling);
19890
+ }, [restartPolling]);
19891
+ React.useEffect(() => {
19892
+ if (restart && !isPolling) {
19893
+ setIsPolling(true);
19894
+ executePoll();
19895
+ setRestart(false);
18294
19896
  }
19897
+ }, [restart]);
19898
+ return {
19899
+ isPolling,
19900
+ isLoading,
19901
+ error,
19902
+ data,
19903
+ startPolling,
19904
+ stopPolling,
19905
+ firstCallLoading,
19906
+ refetch
18295
19907
  };
18296
- const truncateContent = (content, maxLength = 100) => {
18297
- if (content.length <= maxLength) return content;
18298
- return content.substring(0, maxLength) + "...";
18299
- };
18300
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), ref: dropdownRef, children: [
18301
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
18302
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
18303
- /* @__PURE__ */ jsxRuntime.jsx(
18304
- Input,
18305
- {
18306
- type: "text",
18307
- value: query,
18308
- onChange: handleInputChange,
18309
- onKeyDown: handleKeyDown,
18310
- placeholder: "Search memory...",
18311
- className: "pl-10 pr-10 bg-surface3 border-border1"
18312
- }
18313
- ),
18314
- query && /* @__PURE__ */ jsxRuntime.jsx(
18315
- Button$2,
18316
- {
18317
- onClick: clearSearch,
18318
- variant: "ghost",
18319
- size: "sm",
18320
- className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
18321
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
18322
- }
18323
- )
18324
- ] }),
18325
- (isOpen || query && (isSearching || results.length === 0)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex-1 bg-surface3 border border-border1 rounded-lg shadow-lg overflow-y-auto", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-red-500", children: error }) }) : isSearching && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: "Searching..." }) }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon3", children: [
18326
- 'No results found for "',
18327
- query,
18328
- '"'
18329
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
18330
- "button",
18331
- {
18332
- onClick: () => handleResultClick(result.id, result.threadId),
18333
- className: cn(
18334
- "w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
18335
- result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
18336
- ),
18337
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
18338
- result.context?.before && result.context.before.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.before.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
18339
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
18340
- msg.role,
18341
- ":"
18342
- ] }),
18343
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
18344
- ] }, idx)) }),
18345
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
18346
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
18347
- /* @__PURE__ */ jsxRuntime.jsx(
18348
- "span",
18349
- {
18350
- className: cn(
18351
- "text-xs font-medium px-2 py-0.5 rounded",
18352
- result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
18353
- ),
18354
- children: result.role
18355
- }
18356
- ),
18357
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
18358
- result.threadTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
18359
- /* @__PURE__ */ jsxRuntime.jsxs(
18360
- Txt,
18361
- {
18362
- variant: "ui-xs",
18363
- className: cn(
18364
- "truncate max-w-[150px]",
18365
- result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
18366
- ),
18367
- title: result.threadTitle,
18368
- children: [
18369
- "• ",
18370
- result.threadTitle
18371
- ]
18372
- }
18373
- ),
18374
- result.threadId !== currentThreadId && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 text-blue-400" })
18375
- ] })
18376
- ] }),
18377
- /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
18378
- ] }) }),
18379
- result.context?.after && result.context.after.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.after.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
18380
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
18381
- msg.role,
18382
- ":"
18383
- ] }),
18384
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
18385
- ] }, idx)) })
18386
- ] })
18387
- },
18388
- result.id
18389
- )) }) })
18390
- ] });
19908
+ }
19909
+
19910
+ const PlaygroundQueryClient = ({ children }) => {
19911
+ const queryClient = new reactQuery.QueryClient();
19912
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });
18391
19913
  };
18392
19914
 
18393
19915
  const errorFallback = "Something went wrong while fetching the data.";
@@ -18578,6 +20100,234 @@ const EmptyMCPTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "
18578
20100
  }
18579
20101
  ) });
18580
20102
 
20103
+ const useMCPServers = () => {
20104
+ const client = react$3.useMastraClient();
20105
+ const { runtimeContext } = usePlaygroundStore();
20106
+ return reactQuery.useQuery({
20107
+ queryKey: ["mcp-servers"],
20108
+ queryFn: async () => {
20109
+ const mcpServers = (await client.getMcpServers(runtimeContext)).servers;
20110
+ return mcpServers;
20111
+ }
20112
+ });
20113
+ };
20114
+
20115
+ const useMCPServerTool = (serverId, toolId) => {
20116
+ const { runtimeContext } = usePlaygroundStore();
20117
+ const client = react$3.useMastraClient();
20118
+ return reactQuery.useQuery({
20119
+ queryKey: ["mcp-server-tool", serverId, toolId],
20120
+ queryFn: () => {
20121
+ const instance = client.getMcpServerTool(serverId, toolId);
20122
+ return instance.details(runtimeContext);
20123
+ }
20124
+ });
20125
+ };
20126
+ const useExecuteMCPTool = (serverId, toolId) => {
20127
+ const { runtimeContext } = usePlaygroundStore();
20128
+ const client = react$3.useMastraClient();
20129
+ return reactQuery.useMutation({
20130
+ mutationFn: (data) => {
20131
+ const instance = client.getMcpServerTool(serverId, toolId);
20132
+ return instance.execute({ data, runtimeContext });
20133
+ }
20134
+ });
20135
+ };
20136
+
20137
+ const MCPToolPanel = ({ toolId, serverId }) => {
20138
+ const { data: tool, isLoading } = useMCPServerTool(serverId, toolId);
20139
+ const { mutateAsync: executeTool, isPending: isExecuting, data: result } = useExecuteMCPTool(serverId, toolId);
20140
+ const handleExecuteTool = async (data) => {
20141
+ if (!tool) return;
20142
+ return await executeTool(data);
20143
+ };
20144
+ if (isLoading) return null;
20145
+ if (!tool)
20146
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center px-6", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", className: "text-icon3", children: "Tool not found" }) });
20147
+ let zodInputSchema;
20148
+ try {
20149
+ zodInputSchema = resolveSerializedZodOutput(jsonSchemaToZod(tool.inputSchema));
20150
+ } catch (e) {
20151
+ console.error("Error processing input schema:", e);
20152
+ sonner.toast.error("Failed to process tool input schema.");
20153
+ zodInputSchema = z.z.object({});
20154
+ }
20155
+ return /* @__PURE__ */ jsxRuntime.jsx(
20156
+ ToolExecutor,
20157
+ {
20158
+ executionResult: result,
20159
+ isExecutingTool: isExecuting,
20160
+ zodInputSchema,
20161
+ handleExecuteTool,
20162
+ toolDescription: tool.description || "",
20163
+ toolId: tool.id
20164
+ }
20165
+ );
20166
+ };
20167
+
20168
+ const CodeMirrorBlock = (props) => {
20169
+ const theme = useCodemirrorTheme$1();
20170
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-sm border-border1 bg-surface3 p-4 relative", children: [
20171
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 right-4 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy code", content: props.value || "No content" }) }),
20172
+ /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { extensions: [langJson.json()], theme, ...props })
20173
+ ] });
20174
+ };
20175
+
20176
+ const MCPDetail = ({ isLoading, server }) => {
20177
+ const [{ sseUrl, httpStreamUrl }, setUrls] = React.useState({
20178
+ sseUrl: "",
20179
+ httpStreamUrl: ""
20180
+ });
20181
+ React.useEffect(() => {
20182
+ if (!server) return;
20183
+ const host = window.MASTRA_SERVER_HOST;
20184
+ const port = window.MASTRA_SERVER_PORT;
20185
+ let baseUrl = null;
20186
+ if (host && port) {
20187
+ baseUrl = `http://${host}:${port}`;
20188
+ }
20189
+ const effectiveBaseUrl = baseUrl || "http://localhost:4111";
20190
+ const sseUrl2 = `${effectiveBaseUrl}/api/mcp/${server.id}/sse`;
20191
+ const httpStreamUrl2 = `${effectiveBaseUrl}/api/mcp/${server.id}/mcp`;
20192
+ setUrls({ sseUrl: sseUrl2, httpStreamUrl: httpStreamUrl2 });
20193
+ }, [server]);
20194
+ if (isLoading) return null;
20195
+ if (!server)
20196
+ return /* @__PURE__ */ jsxRuntime.jsx(MainContentContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon3 font-medium py-20 text-center", children: "Server not found" }) });
20197
+ return /* @__PURE__ */ jsxRuntime.jsxs(MainContentContent, { isDivided: true, children: [
20198
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-8 py-20 mx-auto max-w-[604px] w-full", children: [
20199
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "h1", variant: "header-md", className: "text-icon6 font-medium pb-4", children: server.name }),
20200
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
20201
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
20202
+ /* @__PURE__ */ jsxRuntime.jsx(
20203
+ Badge$1,
20204
+ {
20205
+ icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "SSE" }),
20206
+ className: "!text-icon4",
20207
+ children: sseUrl
20208
+ }
20209
+ ),
20210
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy SSE URL", content: sseUrl, iconSize: "sm" })
20211
+ ] }),
20212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
20213
+ /* @__PURE__ */ jsxRuntime.jsx(
20214
+ Badge$1,
20215
+ {
20216
+ icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono w-6 text-accent1 text-ui-xs font-medium", children: "HTTP" }),
20217
+ className: "!text-icon4",
20218
+ children: httpStreamUrl
20219
+ }
20220
+ ),
20221
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { tooltip: "Copy HTTP Stream URL", content: httpStreamUrl, iconSize: "sm" })
20222
+ ] })
20223
+ ] }),
20224
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 pt-3 pb-9", children: [
20225
+ /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(FolderIcon, { className: "text-icon6" }), className: "rounded-r-sm !text-icon4", children: "Version" }),
20226
+ /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { className: "rounded-l-sm !text-icon4", children: server.version_detail.version })
20227
+ ] }),
20228
+ /* @__PURE__ */ jsxRuntime.jsx(McpSetupTabs, { sseUrl, serverName: server.name })
20229
+ ] }),
20230
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll border-l-sm border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(McpToolList, { server }) })
20231
+ ] });
20232
+ };
20233
+ const McpSetupTabs = ({ sseUrl, serverName }) => {
20234
+ const { Link } = useLinkComponent();
20235
+ return /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "cursor", children: [
20236
+ /* @__PURE__ */ jsxRuntime.jsxs(TabList$1, { children: [
20237
+ /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "cursor", children: "Cursor" }),
20238
+ /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "windsurf", children: "Windsurf" })
20239
+ ] }),
20240
+ /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "cursor", children: [
20241
+ /* @__PURE__ */ jsxRuntime.jsxs(Txt, { className: "text-icon3 pb-4", children: [
20242
+ "Cursor comes with built-in MCP Support.",
20243
+ " ",
20244
+ /* @__PURE__ */ jsxRuntime.jsx(
20245
+ Link,
20246
+ {
20247
+ href: "https://docs.cursor.com/context/model-context-protocol",
20248
+ target: "_blank",
20249
+ rel: "noopener noreferrer",
20250
+ className: "underline hover:text-icon6",
20251
+ children: "Following the documentation"
20252
+ }
20253
+ ),
20254
+ ", you can register an MCP server using SSE with the following configuration."
20255
+ ] }),
20256
+ /* @__PURE__ */ jsxRuntime.jsx(
20257
+ CodeMirrorBlock,
20258
+ {
20259
+ editable: false,
20260
+ value: `{
20261
+ "mcpServers": {
20262
+ "${serverName}": {
20263
+ "url": "${sseUrl}"
20264
+ }
20265
+ }
20266
+ }`
20267
+ }
20268
+ )
20269
+ ] }),
20270
+ /* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "windsurf", children: [
20271
+ /* @__PURE__ */ jsxRuntime.jsxs(Txt, { className: "text-icon3 pb-4", children: [
20272
+ "Windsurf comes with built-in MCP Support.",
20273
+ " ",
20274
+ /* @__PURE__ */ jsxRuntime.jsx(
20275
+ Link,
20276
+ {
20277
+ href: "https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json",
20278
+ target: "_blank",
20279
+ rel: "noopener noreferrer",
20280
+ className: "underline hover:text-icon6",
20281
+ children: "Following the documentation"
20282
+ }
20283
+ ),
20284
+ ", you can register an MCP server using SSE with the following configuration."
20285
+ ] }),
20286
+ /* @__PURE__ */ jsxRuntime.jsx(
20287
+ CodeMirrorBlock,
20288
+ {
20289
+ editable: false,
20290
+ value: `{
20291
+ "mcpServers": {
20292
+ "${serverName}": {
20293
+ "command": "npx",
20294
+ "args": ["-y", "mcp-remote", "${sseUrl}"]
20295
+ }
20296
+ }
20297
+ }`
20298
+ }
20299
+ )
20300
+ ] })
20301
+ ] });
20302
+ };
20303
+ const McpToolList = ({ server }) => {
20304
+ const { data: tools = {}, isLoading } = useMCPServerTools(server);
20305
+ if (isLoading) return null;
20306
+ const toolsKeyArray = Object.keys(tools);
20307
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 overflow-y-scroll", children: [
20308
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-icon6 flex gap-2 items-center", children: [
20309
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: /* @__PURE__ */ jsxRuntime.jsx(McpServerIcon, {}) }),
20310
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", as: "h2", className: "font-medium", children: "Available Tools" })
20311
+ ] }),
20312
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 pt-6", children: toolsKeyArray.map((toolId) => {
20313
+ const tool = tools[toolId];
20314
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolEntry, { tool, serverId: server.id }, toolId);
20315
+ }) })
20316
+ ] });
20317
+ };
20318
+ const ToolEntry = ({ tool, serverId }) => {
20319
+ const linkRef = React.useRef(null);
20320
+ const { Link, paths } = useLinkComponent();
20321
+ const ToolIconComponent = ToolIconMap[tool.toolType || "tool"];
20322
+ return /* @__PURE__ */ jsxRuntime.jsxs(Entity, { onClick: () => linkRef.current?.click(), children: [
20323
+ /* @__PURE__ */ jsxRuntime.jsx(EntityIcon, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolIconComponent, { className: "group-hover/entity:text-[#ECB047]" }) }),
20324
+ /* @__PURE__ */ jsxRuntime.jsxs(EntityContent, { children: [
20325
+ /* @__PURE__ */ jsxRuntime.jsx(EntityName, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { ref: linkRef, href: paths.mcpServerToolLink(serverId, tool.id), children: tool.id }) }),
20326
+ /* @__PURE__ */ jsxRuntime.jsx(EntityDescription, { children: tool.description })
20327
+ ] })
20328
+ ] });
20329
+ };
20330
+
18581
20331
  const useEvalsByAgentId = (agentId, type) => {
18582
20332
  const { runtimeContext } = usePlaygroundStore();
18583
20333
  const client = react$3.useMastraClient();
@@ -18594,6 +20344,7 @@ exports.AgentCoinIcon = AgentCoinIcon;
18594
20344
  exports.AgentEntityHeader = AgentEntityHeader;
18595
20345
  exports.AgentEvals = AgentEvals;
18596
20346
  exports.AgentIcon = AgentIcon;
20347
+ exports.AgentInformation = AgentInformation;
18597
20348
  exports.AgentMetadata = AgentMetadata;
18598
20349
  exports.AgentMetadataList = AgentMetadataList;
18599
20350
  exports.AgentMetadataListEmpty = AgentMetadataListEmpty;
@@ -18609,6 +20360,7 @@ exports.AgentNetworkCoinIcon = AgentNetworkCoinIcon;
18609
20360
  exports.AgentSettings = AgentSettings;
18610
20361
  exports.AgentSettingsContext = AgentSettingsContext;
18611
20362
  exports.AgentSettingsProvider = AgentSettingsProvider;
20363
+ exports.AgentToolPanel = AgentToolPanel;
18612
20364
  exports.AgentsTable = AgentsTable;
18613
20365
  exports.AiIcon = AiIcon;
18614
20366
  exports.Alert = Alert$1;
@@ -18676,7 +20428,9 @@ exports.KeyValueList = KeyValueList;
18676
20428
  exports.LatencyIcon = LatencyIcon;
18677
20429
  exports.LinkComponentProvider = LinkComponentProvider;
18678
20430
  exports.LogsIcon = LogsIcon;
20431
+ exports.MCPDetail = MCPDetail;
18679
20432
  exports.MCPTable = MCPTable;
20433
+ exports.MCPToolPanel = MCPToolPanel;
18680
20434
  exports.MainContentContent = MainContentContent;
18681
20435
  exports.MainContentLayout = MainContentLayout;
18682
20436
  exports.MainSidebar = MainSidebar;
@@ -18742,6 +20496,9 @@ exports.ThreadList = ThreadList;
18742
20496
  exports.Threads = Threads;
18743
20497
  exports.ToolCoinIcon = ToolCoinIcon;
18744
20498
  exports.ToolFallback = ToolFallback;
20499
+ exports.ToolIconMap = ToolIconMap;
20500
+ exports.ToolInformation = ToolInformation;
20501
+ exports.ToolPanel = ToolPanel;
18745
20502
  exports.ToolTable = ToolTable;
18746
20503
  exports.ToolsIcon = ToolsIcon;
18747
20504
  exports.Tooltip = Tooltip;
@@ -18801,11 +20558,14 @@ exports.useCurrentRun = useCurrentRun;
18801
20558
  exports.useDeleteThread = useDeleteThread;
18802
20559
  exports.useEvalsByAgentId = useEvalsByAgentId;
18803
20560
  exports.useExecuteAgentTool = useExecuteAgentTool;
20561
+ exports.useExecuteMCPTool = useExecuteMCPTool;
18804
20562
  exports.useExecuteTool = useExecuteTool;
18805
20563
  exports.useExecuteWorkflow = useExecuteWorkflow;
18806
20564
  exports.useInView = useInView;
18807
20565
  exports.useLinkComponent = useLinkComponent;
20566
+ exports.useMCPServerTool = useMCPServerTool;
18808
20567
  exports.useMCPServerTools = useMCPServerTools;
20568
+ exports.useMCPServers = useMCPServers;
18809
20569
  exports.useMainSidebar = useMainSidebar;
18810
20570
  exports.useMemory = useMemory;
18811
20571
  exports.useMemoryConfig = useMemoryConfig;
@@ -18824,6 +20584,8 @@ exports.useSpeechRecognition = useSpeechRecognition;
18824
20584
  exports.useStreamWorkflow = useStreamWorkflow;
18825
20585
  exports.useThreadInput = useThreadInput;
18826
20586
  exports.useThreads = useThreads;
20587
+ exports.useTool = useTool;
20588
+ exports.useTools = useTools;
18827
20589
  exports.useTraceSpanScores = useTraceSpanScores;
18828
20590
  exports.useUpdateAgentModel = useUpdateAgentModel;
18829
20591
  exports.useUpdateModelInModelList = useUpdateModelInModelList;