@mastra/playground-ui 66.0.0 → 66.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/domains/traces/components/format-trace-thread-messages.cjs.js +52 -0
  2. package/dist/domains/traces/components/format-trace-thread-messages.cjs.js.map +1 -1
  3. package/dist/domains/traces/components/format-trace-thread-messages.es.js +51 -1
  4. package/dist/domains/traces/components/format-trace-thread-messages.es.js.map +1 -1
  5. package/dist/domains/traces/components/read-only-tool-call-provider.cjs.js +23 -0
  6. package/dist/domains/traces/components/read-only-tool-call-provider.cjs.js.map +1 -0
  7. package/dist/domains/traces/components/read-only-tool-call-provider.d.ts +1 -0
  8. package/dist/domains/traces/components/read-only-tool-call-provider.es.js +22 -0
  9. package/dist/domains/traces/components/read-only-tool-call-provider.es.js.map +1 -0
  10. package/dist/domains/traces/components/span-data-panel-view.cjs.js +123 -67
  11. package/dist/domains/traces/components/span-data-panel-view.cjs.js.map +1 -1
  12. package/dist/domains/traces/components/span-data-panel-view.es.js +131 -75
  13. package/dist/domains/traces/components/span-data-panel-view.es.js.map +1 -1
  14. package/dist/domains/traces/components/span-details-view.cjs.js +19 -11
  15. package/dist/domains/traces/components/span-details-view.cjs.js.map +1 -1
  16. package/dist/domains/traces/components/span-details-view.es.js +22 -14
  17. package/dist/domains/traces/components/span-details-view.es.js.map +1 -1
  18. package/dist/domains/traces/components/span-outcome.cjs.js +78 -0
  19. package/dist/domains/traces/components/span-outcome.cjs.js.map +1 -0
  20. package/dist/domains/traces/components/span-outcome.d.ts +1 -0
  21. package/dist/domains/traces/components/span-outcome.es.js +77 -0
  22. package/dist/domains/traces/components/span-outcome.es.js.map +1 -0
  23. package/dist/domains/traces/components/span-outcome.utils.cjs.js +360 -0
  24. package/dist/domains/traces/components/span-outcome.utils.cjs.js.map +1 -0
  25. package/dist/domains/traces/components/span-outcome.utils.d.ts +1 -0
  26. package/dist/domains/traces/components/span-outcome.utils.es.js +357 -0
  27. package/dist/domains/traces/components/span-outcome.utils.es.js.map +1 -0
  28. package/dist/domains/traces/components/span-payload/span-error-renderer.cjs.js +32 -15
  29. package/dist/domains/traces/components/span-payload/span-error-renderer.cjs.js.map +1 -1
  30. package/dist/domains/traces/components/span-payload/span-error-renderer.es.js +32 -16
  31. package/dist/domains/traces/components/span-payload/span-error-renderer.es.js.map +1 -1
  32. package/dist/domains/traces/components/span-payload/span-input-renderers.cjs.js +2 -2
  33. package/dist/domains/traces/components/span-payload/span-input-renderers.es.js +2 -2
  34. package/dist/domains/traces/components/span-payload/span-output-renderers.cjs.js +2 -10
  35. package/dist/domains/traces/components/span-payload/span-output-renderers.cjs.js.map +1 -1
  36. package/dist/domains/traces/components/span-payload/span-output-renderers.es.js +2 -10
  37. package/dist/domains/traces/components/span-payload/span-output-renderers.es.js.map +1 -1
  38. package/dist/domains/traces/components/span-payload/span-payload-json.cjs.js +22 -1
  39. package/dist/domains/traces/components/span-payload/span-payload-json.cjs.js.map +1 -1
  40. package/dist/domains/traces/components/span-payload/span-payload-json.es.js +22 -1
  41. package/dist/domains/traces/components/span-payload/span-payload-json.es.js.map +1 -1
  42. package/dist/domains/traces/components/span-payload/span-payload-messages.cjs.js +1 -1
  43. package/dist/domains/traces/components/span-payload/span-payload-messages.es.js +1 -1
  44. package/dist/domains/traces/components/span-payload/span-payload-primitives.cjs.js +1 -1
  45. package/dist/domains/traces/components/span-payload/span-payload-primitives.es.js +1 -1
  46. package/dist/domains/traces/components/span-payload/span-payload-processor.cjs.js +4 -7
  47. package/dist/domains/traces/components/span-payload/span-payload-processor.cjs.js.map +1 -1
  48. package/dist/domains/traces/components/span-payload/span-payload-processor.es.js +4 -7
  49. package/dist/domains/traces/components/span-payload/span-payload-processor.es.js.map +1 -1
  50. package/dist/domains/traces/components/span-payload/span-payload-registry.cjs.js +21 -19
  51. package/dist/domains/traces/components/span-payload/span-payload-registry.cjs.js.map +1 -1
  52. package/dist/domains/traces/components/span-payload/span-payload-registry.es.js +22 -20
  53. package/dist/domains/traces/components/span-payload/span-payload-registry.es.js.map +1 -1
  54. package/dist/domains/traces/components/span-payload/span-payload-section.cjs.js +62 -19
  55. package/dist/domains/traces/components/span-payload/span-payload-section.cjs.js.map +1 -1
  56. package/dist/domains/traces/components/span-payload/span-payload-section.es.js +62 -20
  57. package/dist/domains/traces/components/span-payload/span-payload-section.es.js.map +1 -1
  58. package/dist/domains/traces/components/span-payload/span-payload-tool.cjs.js +1 -1
  59. package/dist/domains/traces/components/span-payload/span-payload-tool.es.js +1 -1
  60. package/dist/domains/traces/components/span-payload/span-processor-attributes.cjs.js +51 -140
  61. package/dist/domains/traces/components/span-payload/span-processor-attributes.cjs.js.map +1 -1
  62. package/dist/domains/traces/components/span-payload/span-processor-attributes.es.js +54 -143
  63. package/dist/domains/traces/components/span-payload/span-processor-attributes.es.js.map +1 -1
  64. package/dist/domains/traces/components/span-payload/span-processor-mutations.cjs.js +99 -0
  65. package/dist/domains/traces/components/span-payload/span-processor-mutations.cjs.js.map +1 -0
  66. package/dist/domains/traces/components/span-payload/span-processor-mutations.d.ts +1 -0
  67. package/dist/domains/traces/components/span-payload/span-processor-mutations.es.js +98 -0
  68. package/dist/domains/traces/components/span-payload/span-processor-mutations.es.js.map +1 -0
  69. package/dist/domains/traces/components/span-payload/span-tools-section.cjs.js +48 -3
  70. package/dist/domains/traces/components/span-payload/span-tools-section.cjs.js.map +1 -1
  71. package/dist/domains/traces/components/span-payload/span-tools-section.es.js +48 -5
  72. package/dist/domains/traces/components/span-payload/span-tools-section.es.js.map +1 -1
  73. package/dist/domains/traces/components/span-payload.cjs.js +6 -1
  74. package/dist/domains/traces/components/span-payload.es.js +5 -4
  75. package/dist/domains/traces/components/thread-trace/thread-trace-spans.cjs.js +1 -1
  76. package/dist/domains/traces/components/thread-trace/thread-trace-spans.es.js +1 -1
  77. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +1 -1
  78. package/dist/domains/traces/components/trace-data-panel-view.es.js +1 -1
  79. package/dist/domains/traces/components/trace-details-view.cjs.js +1 -1
  80. package/dist/domains/traces/components/trace-details-view.es.js +1 -1
  81. package/dist/domains/traces/components/trace-thread-item-view.cjs.js +26 -38
  82. package/dist/domains/traces/components/trace-thread-item-view.cjs.js.map +1 -1
  83. package/dist/domains/traces/components/trace-thread-item-view.es.js +26 -38
  84. package/dist/domains/traces/components/trace-thread-item-view.es.js.map +1 -1
  85. package/dist/domains/traces/components.cjs.js +7 -2
  86. package/dist/domains/traces/components.es.js +6 -5
  87. package/dist/domains/traces/hooks/use-trace-span-navigation.cjs.js +1 -1
  88. package/dist/domains/traces/hooks/use-trace-span-navigation.es.js +1 -1
  89. package/dist/domains/traces.cjs.js +7 -2
  90. package/dist/domains/traces.es.js +6 -5
  91. package/dist/{span-payload-primitives-Fi1kSYyM.js → span-payload-primitives-CNDSzk1Q.js} +2 -2
  92. package/dist/{span-payload-primitives-Fi1kSYyM.js.map → span-payload-primitives-CNDSzk1Q.js.map} +1 -1
  93. package/dist/{span-payload-primitives-rxerCV7Y.cjs → span-payload-primitives-DNhjpAtm.cjs} +2 -2
  94. package/dist/{span-payload-primitives-rxerCV7Y.cjs.map → span-payload-primitives-DNhjpAtm.cjs.map} +1 -1
  95. package/dist/src/domains/traces/components/format-trace-thread-messages.d.ts +14 -0
  96. package/dist/src/domains/traces/components/read-only-tool-call-provider.d.ts +5 -0
  97. package/dist/src/domains/traces/components/span-outcome.d.ts +15 -0
  98. package/dist/src/domains/traces/components/span-outcome.utils.d.ts +32 -0
  99. package/dist/src/domains/traces/components/span-payload/index.d.ts +4 -3
  100. package/dist/src/domains/traces/components/span-payload/span-error-renderer.d.ts +2 -0
  101. package/dist/src/domains/traces/components/span-payload/span-payload-json.d.ts +3 -1
  102. package/dist/src/domains/traces/components/span-payload/span-payload-processor.d.ts +1 -4
  103. package/dist/src/domains/traces/components/span-payload/span-payload-registry.d.ts +5 -14
  104. package/dist/src/domains/traces/components/span-payload/span-payload-section.d.ts +20 -1
  105. package/dist/src/domains/traces/components/span-payload/span-processor-attributes.d.ts +4 -4
  106. package/dist/src/domains/traces/components/span-payload/span-processor-mutations.d.ts +5 -0
  107. package/dist/src/domains/traces/components/span-payload/span-tools-section.d.ts +14 -2
  108. package/dist/style.css +22 -2
  109. package/package.json +6 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-processor-mutations.cjs.js","names":["pluralize","Txt","_Fragment","SpanPayloadMessages","SpanPayloadCollapsible","SpanPayloadJson","getSpanChanges"],"sources":["../../../../../src/domains/traces/components/span-payload/span-processor-mutations.tsx"],"sourcesContent":["import type { ProcessorPipelineDescription } from '@mastra/core/observability';\nimport type { SpanRecord } from '../../types';\nimport { getSpanChanges } from '../span-outcome.utils';\nimport { SpanPayloadJson } from './span-payload-json';\nimport { SpanPayloadMessages } from './span-payload-messages';\nimport { SpanPayloadCollapsible } from './span-payload-primitives';\nimport { Txt } from '@/ds/components/Txt/Txt';\nimport { pluralize } from '@/lib/string';\n\ntype Mutation = NonNullable<ProcessorPipelineDescription['messageListMutations']>[number];\n\nconst messages = (count: number | undefined) => (count === undefined ? 'messages' : pluralize(count, 'message'));\n\n/** What a recorded change did to the message list, as one sentence. */\nfunction describeMutation(mutation: Exclude<Mutation, null | undefined>): string {\n const { type, source, count, tag } = mutation;\n switch (type) {\n case 'add':\n if (source === 'memory') return `Added ${messages(count)} from memory to the conversation`;\n if (source === 'input') return `Added ${messages(count)} to this turn's input`;\n if (source === 'response') return `Added ${messages(count)} to the model's response`;\n if (source === 'context') return `Added ${messages(count)} of context to the conversation`;\n if (source === 'system') return `Added ${messages(count)} to the system prompt`;\n return `Added ${messages(count)} to the conversation`;\n case 'addSystem':\n return `Added ${count && count > 1 ? messages(count) : 'a'}${tag ? ` \"${tag}\"` : ''}${count && count > 1 ? '' : ' message'} to the system prompt`;\n case 'clear':\n if (source === 'input') return `Took ${messages(count)} from this turn's input out of the conversation`;\n if (source === 'response') return `Took ${messages(count)} from the model's response out of the conversation`;\n return `Cleared the whole conversation (${messages(count)})`;\n case 'removeByIds':\n if (source === 'system') return `Removed ${messages(count ?? mutation.ids?.length)} from the system prompt`;\n return `Removed ${messages(count ?? mutation.ids?.length)} from the conversation`;\n default:\n return `${String(type)}${source ? ` (${source})` : ''}`;\n }\n}\n\n/**\n * The recorded changes in the order they happened. Back-to-back changes of the same\n * kind that only carry a count (e.g. two single-message adds from memory) read as one step.\n */\nfunction toSteps(mutations: readonly Mutation[]) {\n const steps: Mutation[] = [];\n for (const mutation of mutations) {\n const previous = steps.at(-1);\n if (isCountOnly(previous) && isCountOnly(mutation) && isSameKind(previous, mutation)) {\n steps[steps.length - 1] = { ...previous, count: previous.count + mutation.count };\n continue;\n }\n steps.push(mutation);\n }\n return steps;\n}\n\ntype CountOnlyMutation = Exclude<Mutation, null | undefined> & { count: number };\n\nconst isCountOnly = (mutation: Mutation | undefined): mutation is CountOnlyMutation =>\n typeof mutation === 'object' &&\n mutation !== null &&\n mutation.count !== undefined &&\n mutation.message === undefined &&\n !(mutation.ids && mutation.ids.length > 0);\n\nconst isSameKind = (a: CountOnlyMutation, b: CountOnlyMutation) =>\n a.type === b.type && a.source === b.source && a.tag === b.tag;\n\nfunction MutationSteps({ mutations }: { mutations: readonly Mutation[] }) {\n const steps = toSteps(mutations);\n return (\n <ol data-slot=\"span-processor-mutations\" className=\"flex list-none flex-col divide-y divide-border\">\n {steps.map((mutation, index) => (\n <li key={index} className=\"flex gap-3 py-3 first:pt-0 last:pb-0\">\n {/* Numbers only help to read several steps in order. */}\n {steps.length > 1 && (\n <Txt as=\"span\" variant=\"body-sm\" tone=\"faint\" font=\"mono\" className=\"tabular-nums\">\n {index + 1}.\n </Txt>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {typeof mutation === 'object' && mutation !== null ? (\n <>\n {/* An added message speaks for itself; anything else needs saying what happened to it. */}\n {(mutation.message === undefined || mutation.type === 'removeByIds') && (\n <Txt as=\"p\" variant=\"body-sm\" tone=\"ink\" data-slot=\"span-processor-mutation-step\">\n {describeMutation(mutation)}\n </Txt>\n )}\n {mutation.message !== undefined && <SpanPayloadMessages value={[mutation.message]} />}\n {mutation.ids && mutation.ids.length > 0 && (\n <SpanPayloadCollapsible label={`Removed ids (${mutation.ids.length})`}>\n <SpanPayloadJson value={mutation.ids} />\n </SpanPayloadCollapsible>\n )}\n </>\n ) : (\n <SpanPayloadJson value={mutation} />\n )}\n </div>\n </li>\n ))}\n </ol>\n );\n}\n\n/** What a pipeline span changed in the message list, step by step; `null` when it changed nothing. */\nexport function SpanProcessorMutations({ span }: { span: SpanRecord }) {\n const mutations = getSpanChanges(span);\n if (mutations.length === 0) return null;\n\n return (\n <div data-slot=\"span-processor-changes\">\n <MutationSteps mutations={mutations} />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from '../../../../src/domains/traces/components/span-payload/span-processor-mutations';
@@ -0,0 +1,98 @@
1
+ import { t as Txt } from "../../../../Txt-BM6TVV_c.js";
2
+ import { n as pluralize } from "../../../../string-OAgeMRQ5.js";
3
+ import { getSpanChanges } from "../span-outcome.utils.es.js";
4
+ import { SpanPayloadJson } from "./span-payload-json.es.js";
5
+ import { t as SpanPayloadCollapsible } from "../../../../span-payload-primitives-CNDSzk1Q.js";
6
+ import { SpanPayloadMessages } from "./span-payload-messages.es.js";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ // src/domains/traces/components/span-payload/span-processor-mutations.tsx
9
+ var messages = (count) => count === void 0 ? "messages" : pluralize(count, "message");
10
+ /** What a recorded change did to the message list, as one sentence. */
11
+ function describeMutation(mutation) {
12
+ const { type, source, count, tag } = mutation;
13
+ switch (type) {
14
+ case "add":
15
+ if (source === "memory") return `Added ${messages(count)} from memory to the conversation`;
16
+ if (source === "input") return `Added ${messages(count)} to this turn's input`;
17
+ if (source === "response") return `Added ${messages(count)} to the model's response`;
18
+ if (source === "context") return `Added ${messages(count)} of context to the conversation`;
19
+ if (source === "system") return `Added ${messages(count)} to the system prompt`;
20
+ return `Added ${messages(count)} to the conversation`;
21
+ case "addSystem": return `Added ${count && count > 1 ? messages(count) : "a"}${tag ? ` "${tag}"` : ""}${count && count > 1 ? "" : " message"} to the system prompt`;
22
+ case "clear":
23
+ if (source === "input") return `Took ${messages(count)} from this turn's input out of the conversation`;
24
+ if (source === "response") return `Took ${messages(count)} from the model's response out of the conversation`;
25
+ return `Cleared the whole conversation (${messages(count)})`;
26
+ case "removeByIds":
27
+ if (source === "system") return `Removed ${messages(count ?? mutation.ids?.length)} from the system prompt`;
28
+ return `Removed ${messages(count ?? mutation.ids?.length)} from the conversation`;
29
+ default: return `${String(type)}${source ? ` (${source})` : ""}`;
30
+ }
31
+ }
32
+ /**
33
+ * The recorded changes in the order they happened. Back-to-back changes of the same
34
+ * kind that only carry a count (e.g. two single-message adds from memory) read as one step.
35
+ */
36
+ function toSteps(mutations) {
37
+ const steps = [];
38
+ for (const mutation of mutations) {
39
+ const previous = steps.at(-1);
40
+ if (isCountOnly(previous) && isCountOnly(mutation) && isSameKind(previous, mutation)) {
41
+ steps[steps.length - 1] = {
42
+ ...previous,
43
+ count: previous.count + mutation.count
44
+ };
45
+ continue;
46
+ }
47
+ steps.push(mutation);
48
+ }
49
+ return steps;
50
+ }
51
+ var isCountOnly = (mutation) => typeof mutation === "object" && mutation !== null && mutation.count !== void 0 && mutation.message === void 0 && !(mutation.ids && mutation.ids.length > 0);
52
+ var isSameKind = (a, b) => a.type === b.type && a.source === b.source && a.tag === b.tag;
53
+ function MutationSteps({ mutations }) {
54
+ const steps = toSteps(mutations);
55
+ return /* @__PURE__ */ jsx("ol", {
56
+ "data-slot": "span-processor-mutations",
57
+ className: "flex list-none flex-col divide-y divide-border",
58
+ children: steps.map((mutation, index) => /* @__PURE__ */ jsxs("li", {
59
+ className: "flex gap-3 py-3 first:pt-0 last:pb-0",
60
+ children: [steps.length > 1 && /* @__PURE__ */ jsxs(Txt, {
61
+ as: "span",
62
+ variant: "body-sm",
63
+ tone: "faint",
64
+ font: "mono",
65
+ className: "tabular-nums",
66
+ children: [index + 1, "."]
67
+ }), /* @__PURE__ */ jsx("div", {
68
+ className: "flex min-w-0 flex-1 flex-col gap-2",
69
+ children: typeof mutation === "object" && mutation !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [
70
+ (mutation.message === void 0 || mutation.type === "removeByIds") && /* @__PURE__ */ jsx(Txt, {
71
+ as: "p",
72
+ variant: "body-sm",
73
+ tone: "ink",
74
+ "data-slot": "span-processor-mutation-step",
75
+ children: describeMutation(mutation)
76
+ }),
77
+ mutation.message !== void 0 && /* @__PURE__ */ jsx(SpanPayloadMessages, { value: [mutation.message] }),
78
+ mutation.ids && mutation.ids.length > 0 && /* @__PURE__ */ jsx(SpanPayloadCollapsible, {
79
+ label: `Removed ids (${mutation.ids.length})`,
80
+ children: /* @__PURE__ */ jsx(SpanPayloadJson, { value: mutation.ids })
81
+ })
82
+ ] }) : /* @__PURE__ */ jsx(SpanPayloadJson, { value: mutation })
83
+ })]
84
+ }, index))
85
+ });
86
+ }
87
+ /** What a pipeline span changed in the message list, step by step; `null` when it changed nothing. */
88
+ function SpanProcessorMutations({ span }) {
89
+ const mutations = getSpanChanges(span);
90
+ if (mutations.length === 0) return null;
91
+ return /* @__PURE__ */ jsx("div", {
92
+ "data-slot": "span-processor-changes",
93
+ children: /* @__PURE__ */ jsx(MutationSteps, { mutations })
94
+ });
95
+ }
96
+ export { SpanProcessorMutations };
97
+
98
+ //# sourceMappingURL=span-processor-mutations.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-processor-mutations.es.js","names":["_Fragment"],"sources":["../../../../../src/domains/traces/components/span-payload/span-processor-mutations.tsx"],"sourcesContent":["import type { ProcessorPipelineDescription } from '@mastra/core/observability';\nimport type { SpanRecord } from '../../types';\nimport { getSpanChanges } from '../span-outcome.utils';\nimport { SpanPayloadJson } from './span-payload-json';\nimport { SpanPayloadMessages } from './span-payload-messages';\nimport { SpanPayloadCollapsible } from './span-payload-primitives';\nimport { Txt } from '@/ds/components/Txt/Txt';\nimport { pluralize } from '@/lib/string';\n\ntype Mutation = NonNullable<ProcessorPipelineDescription['messageListMutations']>[number];\n\nconst messages = (count: number | undefined) => (count === undefined ? 'messages' : pluralize(count, 'message'));\n\n/** What a recorded change did to the message list, as one sentence. */\nfunction describeMutation(mutation: Exclude<Mutation, null | undefined>): string {\n const { type, source, count, tag } = mutation;\n switch (type) {\n case 'add':\n if (source === 'memory') return `Added ${messages(count)} from memory to the conversation`;\n if (source === 'input') return `Added ${messages(count)} to this turn's input`;\n if (source === 'response') return `Added ${messages(count)} to the model's response`;\n if (source === 'context') return `Added ${messages(count)} of context to the conversation`;\n if (source === 'system') return `Added ${messages(count)} to the system prompt`;\n return `Added ${messages(count)} to the conversation`;\n case 'addSystem':\n return `Added ${count && count > 1 ? messages(count) : 'a'}${tag ? ` \"${tag}\"` : ''}${count && count > 1 ? '' : ' message'} to the system prompt`;\n case 'clear':\n if (source === 'input') return `Took ${messages(count)} from this turn's input out of the conversation`;\n if (source === 'response') return `Took ${messages(count)} from the model's response out of the conversation`;\n return `Cleared the whole conversation (${messages(count)})`;\n case 'removeByIds':\n if (source === 'system') return `Removed ${messages(count ?? mutation.ids?.length)} from the system prompt`;\n return `Removed ${messages(count ?? mutation.ids?.length)} from the conversation`;\n default:\n return `${String(type)}${source ? ` (${source})` : ''}`;\n }\n}\n\n/**\n * The recorded changes in the order they happened. Back-to-back changes of the same\n * kind that only carry a count (e.g. two single-message adds from memory) read as one step.\n */\nfunction toSteps(mutations: readonly Mutation[]) {\n const steps: Mutation[] = [];\n for (const mutation of mutations) {\n const previous = steps.at(-1);\n if (isCountOnly(previous) && isCountOnly(mutation) && isSameKind(previous, mutation)) {\n steps[steps.length - 1] = { ...previous, count: previous.count + mutation.count };\n continue;\n }\n steps.push(mutation);\n }\n return steps;\n}\n\ntype CountOnlyMutation = Exclude<Mutation, null | undefined> & { count: number };\n\nconst isCountOnly = (mutation: Mutation | undefined): mutation is CountOnlyMutation =>\n typeof mutation === 'object' &&\n mutation !== null &&\n mutation.count !== undefined &&\n mutation.message === undefined &&\n !(mutation.ids && mutation.ids.length > 0);\n\nconst isSameKind = (a: CountOnlyMutation, b: CountOnlyMutation) =>\n a.type === b.type && a.source === b.source && a.tag === b.tag;\n\nfunction MutationSteps({ mutations }: { mutations: readonly Mutation[] }) {\n const steps = toSteps(mutations);\n return (\n <ol data-slot=\"span-processor-mutations\" className=\"flex list-none flex-col divide-y divide-border\">\n {steps.map((mutation, index) => (\n <li key={index} className=\"flex gap-3 py-3 first:pt-0 last:pb-0\">\n {/* Numbers only help to read several steps in order. */}\n {steps.length > 1 && (\n <Txt as=\"span\" variant=\"body-sm\" tone=\"faint\" font=\"mono\" className=\"tabular-nums\">\n {index + 1}.\n </Txt>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {typeof mutation === 'object' && mutation !== null ? (\n <>\n {/* An added message speaks for itself; anything else needs saying what happened to it. */}\n {(mutation.message === undefined || mutation.type === 'removeByIds') && (\n <Txt as=\"p\" variant=\"body-sm\" tone=\"ink\" data-slot=\"span-processor-mutation-step\">\n {describeMutation(mutation)}\n </Txt>\n )}\n {mutation.message !== undefined && <SpanPayloadMessages value={[mutation.message]} />}\n {mutation.ids && mutation.ids.length > 0 && (\n <SpanPayloadCollapsible label={`Removed ids (${mutation.ids.length})`}>\n <SpanPayloadJson value={mutation.ids} />\n </SpanPayloadCollapsible>\n )}\n </>\n ) : (\n <SpanPayloadJson value={mutation} />\n )}\n </div>\n </li>\n ))}\n </ol>\n );\n}\n\n/** What a pipeline span changed in the message list, step by step; `null` when it changed nothing. */\nexport function SpanProcessorMutations({ span }: { span: SpanRecord }) {\n const mutations = getSpanChanges(span);\n if (mutations.length === 0) return null;\n\n return (\n <div data-slot=\"span-processor-changes\">\n <MutationSteps mutations={mutations} />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -2,10 +2,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_lib_framework = require("../../../../lib/framework.cjs.js");
3
3
  const require_Txt = require("../../../../Txt-BnoSqxKE.cjs");
4
4
  const require_icons_ToolsIcon = require("../../../../icons/ToolsIcon.cjs.js");
5
+ const require_domains_chat_messages_message_row = require("../../../chat/messages/message-row.cjs.js");
6
+ const require_domains_traces_components_format_trace_thread_messages = require("../format-trace-thread-messages.cjs.js");
5
7
  const require_domains_traces_components_span_payload_span_payload_registry = require("./span-payload-registry.cjs.js");
6
- const require_span_payload_primitives = require("../../../../span-payload-primitives-rxerCV7Y.cjs");
8
+ const require_span_payload_primitives = require("../../../../span-payload-primitives-DNhjpAtm.cjs");
7
9
  const require_domains_traces_components_span_payload_span_payload_section = require("./span-payload-section.cjs.js");
10
+ const require_domains_traces_components_read_only_tool_call_provider = require("../read-only-tool-call-provider.cjs.js");
8
11
  let react_jsx_runtime = require("react/jsx-runtime");
12
+ let _mastra_react_hooks_traces = require("@mastra/react/hooks/traces");
9
13
  let _mastra_react_hooks_tools = require("@mastra/react/hooks/tools");
10
14
  // src/domains/traces/components/span-payload/span-tools-section.tsx
11
15
  /**
@@ -45,18 +49,59 @@ function SpanToolList({ tools }) {
45
49
  })
46
50
  });
47
51
  }
48
- /** The tools the span offered the model. */
52
+ /**
53
+ * The tools the model called, each opening on its input and result like in the chat,
54
+ * then the tools the span offered the model.
55
+ */
49
56
  function SpanToolsSection({ span, layout }) {
57
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [require_domains_traces_components_format_trace_thread_messages.getRequestedToolCalls(span).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SpanToolCallsSection, {
58
+ span,
59
+ layout
60
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SpanAvailableToolsSection, {
61
+ span,
62
+ layout
63
+ })] });
64
+ }
65
+ /** The tools the model called, each opening on its input and the result its tool span recorded. */
66
+ function SpanToolCallsSection({ span, layout, heading }) {
67
+ const { data } = (0, _mastra_react_hooks_traces.useTraceSpans)({
68
+ traceId: span.traceId,
69
+ passive: true
70
+ });
71
+ const toolCalls = require_domains_traces_components_format_trace_thread_messages.formatSpanToolCallMessages(span, data?.spans ?? []);
72
+ if (toolCalls.length === 0) return null;
73
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_traces_components_span_payload_span_payload_section.SpanPayloadSection, {
74
+ title: `Tool calls (${toolCalls.length})`,
75
+ heading,
76
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_ToolsIcon.ToolsIcon, {}),
77
+ raw: require_domains_traces_components_format_trace_thread_messages.getRequestedToolCalls(span),
78
+ hasPreview: true,
79
+ clip: false,
80
+ layout,
81
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
82
+ "data-slot": "span-tool-calls",
83
+ className: "flex flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0",
84
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_traces_components_read_only_tool_call_provider.ReadOnlyToolCallProvider, { children: toolCalls.map((message) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_messages_message_row.MessageRow, {
85
+ message,
86
+ readOnly: true
87
+ }, message.id)) })
88
+ })
89
+ });
90
+ }
91
+ /** The tools the span offered the model, linking to their pages when registered. */
92
+ function SpanAvailableToolsSection({ span, layout }) {
50
93
  const spanTools = require_domains_traces_components_span_payload_span_payload_registry.getSpanTools(span);
51
94
  if (!spanTools) return null;
52
95
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_traces_components_span_payload_span_payload_section.SpanPayloadSection, {
53
- title: `Tools (${spanTools.tools.length})`,
96
+ title: `Available tools (${spanTools.tools.length})`,
54
97
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_ToolsIcon.ToolsIcon, {}),
55
98
  raw: spanTools.raw,
56
99
  layout,
57
100
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SpanToolList, { tools: spanTools.tools })
58
101
  });
59
102
  }
103
+ exports.SpanAvailableToolsSection = SpanAvailableToolsSection;
104
+ exports.SpanToolCallsSection = SpanToolCallsSection;
60
105
  exports.SpanToolsSection = SpanToolsSection;
61
106
 
62
107
  //# sourceMappingURL=span-tools-section.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"span-tools-section.cjs.js","names":["useTools","useLinkComponent","SpanPayloadList","getDelegatedToolHref","Txt","SpanPayloadListName","getSpanTools","SpanPayloadSection","ToolsIcon"],"sources":["../../../../../src/domains/traces/components/span-payload/span-tools-section.tsx"],"sourcesContent":["import { useTools } from '@mastra/react/hooks/tools';\nimport type { SpanRecord } from '../../types';\nimport { SpanPayloadList, SpanPayloadListName } from './span-payload-primitives';\nimport { getDelegatedToolHref, getSpanTools } from './span-payload-registry';\nimport type { SpanTool } from './span-payload-registry';\nimport { SpanPayloadSection } from './span-payload-section';\nimport type { SpanPayloadSectionProps } from './span-payload-section';\nimport { Txt } from '@/ds/components/Txt';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\n/**\n * Registered tool ids by the names a span may record them under: the tool id,\n * or the key it is registered with (what model spans pass to the provider).\n */\nfunction useRegisteredToolIds(): Map<string, string> {\n const { data: tools = {} } = useTools();\n const ids = new Map<string, string>();\n for (const [key, tool] of Object.entries(tools)) {\n ids.set(key, tool.id);\n ids.set(tool.id, tool.id);\n }\n return ids;\n}\n\nfunction SpanToolList({ tools }: { tools: SpanTool[] }) {\n const { Link, paths } = useLinkComponent();\n const registered = useRegisteredToolIds();\n\n return (\n <SpanPayloadList\n slot=\"span-tools\"\n items={tools.map(tool => {\n const registeredId = registered.get(tool.id);\n // Workspace, skill and agent-only tools are not in the registry, so they have no page to open.\n const href = getDelegatedToolHref(paths, tool.id) || (registeredId ? paths.toolLink(registeredId) : '');\n return {\n key: tool.id,\n description: tool.description,\n name: href ? (\n <Link href={href} className=\"w-fit max-w-full truncate text-foreground hover:underline\">\n <Txt as=\"span\" variant=\"label\">\n {tool.id}\n </Txt>\n </Link>\n ) : (\n <SpanPayloadListName>{tool.id}</SpanPayloadListName>\n ),\n };\n })}\n />\n );\n}\n\nexport interface SpanToolsSectionProps {\n span: SpanRecord;\n layout?: SpanPayloadSectionProps['layout'];\n}\n\n/** The tools the span offered the model. */\nexport function SpanToolsSection({ span, layout }: SpanToolsSectionProps) {\n const spanTools = getSpanTools(span);\n if (!spanTools) return null;\n\n return (\n <SpanPayloadSection\n title={`Tools (${spanTools.tools.length})`}\n icon={<ToolsIcon />}\n raw={spanTools.raw}\n layout={layout}\n >\n <SpanToolList tools={spanTools.tools} />\n </SpanPayloadSection>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAS,uBAA4C;CACnD,MAAM,EAAE,MAAM,QAAQ,CAAC,OAAA,GAAMA,0BAAAA,SAAAA,CAAS;CACtC,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAC/C,IAAI,IAAI,KAAK,KAAK,EAAE;EACpB,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE;CAC1B;CACA,OAAO;AACT;AAEA,SAAS,aAAa,EAAE,SAAgC;CACtD,MAAM,EAAE,MAAM,UAAUC,sBAAAA,iBAAiB;CACzC,MAAM,aAAa,qBAAqB;CAExC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,gCAAAA,iBAAD;EACE,MAAK;EACL,OAAO,MAAM,KAAI,SAAQ;GACvB,MAAM,eAAe,WAAW,IAAI,KAAK,EAAE;GAE3C,MAAM,OAAOC,qEAAAA,qBAAqB,OAAO,KAAK,EAAE,MAAM,eAAe,MAAM,SAAS,YAAY,IAAI;GACpG,OAAO;IACL,KAAK,KAAK;IACV,aAAa,KAAK;IAClB,MAAM,OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;KAAY;KAAM,WAAU;KAC1B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,YAAAA,KAAD;MAAK,IAAG;MAAO,SAAQ;MACpB,UAAA,KAAK;KACH,CAAA;IACD,CAAA,IAEN,iBAAA,GAAA,kBAAA,IAAA,CAACC,gCAAAA,qBAAD,EAAA,UAAsB,KAAK,GAAwB,CAAA;GAEvD;EACF,CAAC;CACF,CAAA;AAEL;;AAQA,SAAgB,iBAAiB,EAAE,MAAM,UAAiC;CACxE,MAAM,YAAYC,qEAAAA,aAAa,IAAI;CACnC,IAAI,CAAC,WAAW,OAAO;CAEvB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,oEAAAA,oBAAD;EACE,OAAO,UAAU,UAAU,MAAM,OAAO;EACxC,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,wBAAAA,WAAD,CAAY,CAAA;EAClB,KAAK,UAAU;EACP;EAER,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAc,OAAO,UAAU,MAAQ,CAAA;CACrB,CAAA;AAExB"}
1
+ {"version":3,"file":"span-tools-section.cjs.js","names":["useTools","useLinkComponent","SpanPayloadList","getDelegatedToolHref","Txt","SpanPayloadListName","_Fragment","getRequestedToolCalls","useTraceSpans","formatSpanToolCallMessages","SpanPayloadSection","ToolsIcon","ReadOnlyToolCallProvider","MessageRow","getSpanTools"],"sources":["../../../../../src/domains/traces/components/span-payload/span-tools-section.tsx"],"sourcesContent":["import { useTools } from '@mastra/react/hooks/tools';\nimport { useTraceSpans } from '@mastra/react/hooks/traces';\nimport type { ReactNode } from 'react';\nimport type { SpanRecord } from '../../types';\nimport { formatSpanToolCallMessages, getRequestedToolCalls } from '../format-trace-thread-messages';\nimport { ReadOnlyToolCallProvider } from '../read-only-tool-call-provider';\nimport { SpanPayloadList, SpanPayloadListName } from './span-payload-primitives';\nimport { getDelegatedToolHref, getSpanTools } from './span-payload-registry';\nimport type { SpanTool } from './span-payload-registry';\nimport { SpanPayloadSection } from './span-payload-section';\nimport type { SpanPayloadSectionProps } from './span-payload-section';\nimport { MessageRow } from '@/domains/chat/messages/message-row';\nimport { Txt } from '@/ds/components/Txt';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\n/**\n * Registered tool ids by the names a span may record them under: the tool id,\n * or the key it is registered with (what model spans pass to the provider).\n */\nfunction useRegisteredToolIds(): Map<string, string> {\n const { data: tools = {} } = useTools();\n const ids = new Map<string, string>();\n for (const [key, tool] of Object.entries(tools)) {\n ids.set(key, tool.id);\n ids.set(tool.id, tool.id);\n }\n return ids;\n}\n\nfunction SpanToolList({ tools }: { tools: SpanTool[] }) {\n const { Link, paths } = useLinkComponent();\n const registered = useRegisteredToolIds();\n\n return (\n <SpanPayloadList\n slot=\"span-tools\"\n items={tools.map(tool => {\n const registeredId = registered.get(tool.id);\n // Workspace, skill and agent-only tools are not in the registry, so they have no page to open.\n const href = getDelegatedToolHref(paths, tool.id) || (registeredId ? paths.toolLink(registeredId) : '');\n return {\n key: tool.id,\n description: tool.description,\n name: href ? (\n <Link href={href} className=\"w-fit max-w-full truncate text-foreground hover:underline\">\n <Txt as=\"span\" variant=\"label\">\n {tool.id}\n </Txt>\n </Link>\n ) : (\n <SpanPayloadListName>{tool.id}</SpanPayloadListName>\n ),\n };\n })}\n />\n );\n}\n\nexport interface SpanToolsSectionProps {\n span: SpanRecord;\n layout?: SpanPayloadSectionProps['layout'];\n}\n\n/**\n * The tools the model called, each opening on its input and result like in the chat,\n * then the tools the span offered the model.\n */\nexport function SpanToolsSection({ span, layout }: SpanToolsSectionProps) {\n return (\n <>\n {getRequestedToolCalls(span).length > 0 && <SpanToolCallsSection span={span} layout={layout} />}\n <SpanAvailableToolsSection span={span} layout={layout} />\n </>\n );\n}\n\nexport interface SpanToolCallsSectionProps extends SpanToolsSectionProps {\n /** Replaces the \"Tool calls\" heading, e.g. with the sentence of the notice the section sits in. */\n heading?: ReactNode;\n}\n\n/** The tools the model called, each opening on its input and the result its tool span recorded. */\nexport function SpanToolCallsSection({ span, layout, heading }: SpanToolCallsSectionProps) {\n // The results live on the tool spans, which the trace panel has usually loaded already.\n const { data } = useTraceSpans({ traceId: span.traceId, passive: true });\n const toolCalls = formatSpanToolCallMessages(span, data?.spans ?? []);\n // Only tools the chat never draws (task tools, working memory) were called; the Output JSON keeps them.\n if (toolCalls.length === 0) return null;\n\n return (\n <SpanPayloadSection\n title={`Tool calls (${toolCalls.length})`}\n heading={heading}\n icon={<ToolsIcon />}\n raw={getRequestedToolCalls(span)}\n hasPreview\n // Each call folds on its own, so the list never needs clipping.\n clip={false}\n layout={layout}\n >\n {/* Tool rows carry their own vertical margins; strip them at the edges so the card padding is the only outer spacing. */}\n <div\n data-slot=\"span-tool-calls\"\n className=\"flex flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0\"\n >\n <ReadOnlyToolCallProvider>\n {toolCalls.map(message => (\n <MessageRow key={message.id} message={message} readOnly />\n ))}\n </ReadOnlyToolCallProvider>\n </div>\n </SpanPayloadSection>\n );\n}\n\n/** The tools the span offered the model, linking to their pages when registered. */\nexport function SpanAvailableToolsSection({ span, layout }: SpanToolsSectionProps) {\n const spanTools = getSpanTools(span);\n if (!spanTools) return null;\n\n return (\n <SpanPayloadSection\n title={`Available tools (${spanTools.tools.length})`}\n icon={<ToolsIcon />}\n raw={spanTools.raw}\n layout={layout}\n >\n <SpanToolList tools={spanTools.tools} />\n </SpanPayloadSection>\n );\n}\n"],"mappings":"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"}
@@ -1,10 +1,14 @@
1
1
  import { useLinkComponent } from "../../../../lib/framework.es.js";
2
2
  import { t as Txt } from "../../../../Txt-BM6TVV_c.js";
3
3
  import { ToolsIcon } from "../../../../icons/ToolsIcon.es.js";
4
+ import { MessageRow } from "../../../chat/messages/message-row.es.js";
5
+ import { formatSpanToolCallMessages, getRequestedToolCalls } from "../format-trace-thread-messages.es.js";
4
6
  import { getDelegatedToolHref, getSpanTools } from "./span-payload-registry.es.js";
5
- import { a as SpanPayloadListName, i as SpanPayloadList } from "../../../../span-payload-primitives-Fi1kSYyM.js";
7
+ import { a as SpanPayloadListName, i as SpanPayloadList } from "../../../../span-payload-primitives-CNDSzk1Q.js";
6
8
  import { SpanPayloadSection } from "./span-payload-section.es.js";
7
- import { jsx } from "react/jsx-runtime";
9
+ import { ReadOnlyToolCallProvider } from "../read-only-tool-call-provider.es.js";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { useTraceSpans } from "@mastra/react/hooks/traces";
8
12
  import { useTools } from "@mastra/react/hooks/tools";
9
13
  // src/domains/traces/components/span-payload/span-tools-section.tsx
10
14
  /**
@@ -44,18 +48,57 @@ function SpanToolList({ tools }) {
44
48
  })
45
49
  });
46
50
  }
47
- /** The tools the span offered the model. */
51
+ /**
52
+ * The tools the model called, each opening on its input and result like in the chat,
53
+ * then the tools the span offered the model.
54
+ */
48
55
  function SpanToolsSection({ span, layout }) {
56
+ return /* @__PURE__ */ jsxs(Fragment, { children: [getRequestedToolCalls(span).length > 0 && /* @__PURE__ */ jsx(SpanToolCallsSection, {
57
+ span,
58
+ layout
59
+ }), /* @__PURE__ */ jsx(SpanAvailableToolsSection, {
60
+ span,
61
+ layout
62
+ })] });
63
+ }
64
+ /** The tools the model called, each opening on its input and the result its tool span recorded. */
65
+ function SpanToolCallsSection({ span, layout, heading }) {
66
+ const { data } = useTraceSpans({
67
+ traceId: span.traceId,
68
+ passive: true
69
+ });
70
+ const toolCalls = formatSpanToolCallMessages(span, data?.spans ?? []);
71
+ if (toolCalls.length === 0) return null;
72
+ return /* @__PURE__ */ jsx(SpanPayloadSection, {
73
+ title: `Tool calls (${toolCalls.length})`,
74
+ heading,
75
+ icon: /* @__PURE__ */ jsx(ToolsIcon, {}),
76
+ raw: getRequestedToolCalls(span),
77
+ hasPreview: true,
78
+ clip: false,
79
+ layout,
80
+ children: /* @__PURE__ */ jsx("div", {
81
+ "data-slot": "span-tool-calls",
82
+ className: "flex flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0",
83
+ children: /* @__PURE__ */ jsx(ReadOnlyToolCallProvider, { children: toolCalls.map((message) => /* @__PURE__ */ jsx(MessageRow, {
84
+ message,
85
+ readOnly: true
86
+ }, message.id)) })
87
+ })
88
+ });
89
+ }
90
+ /** The tools the span offered the model, linking to their pages when registered. */
91
+ function SpanAvailableToolsSection({ span, layout }) {
49
92
  const spanTools = getSpanTools(span);
50
93
  if (!spanTools) return null;
51
94
  return /* @__PURE__ */ jsx(SpanPayloadSection, {
52
- title: `Tools (${spanTools.tools.length})`,
95
+ title: `Available tools (${spanTools.tools.length})`,
53
96
  icon: /* @__PURE__ */ jsx(ToolsIcon, {}),
54
97
  raw: spanTools.raw,
55
98
  layout,
56
99
  children: /* @__PURE__ */ jsx(SpanToolList, { tools: spanTools.tools })
57
100
  });
58
101
  }
59
- export { SpanToolsSection };
102
+ export { SpanAvailableToolsSection, SpanToolCallsSection, SpanToolsSection };
60
103
 
61
104
  //# sourceMappingURL=span-tools-section.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"span-tools-section.es.js","names":[],"sources":["../../../../../src/domains/traces/components/span-payload/span-tools-section.tsx"],"sourcesContent":["import { useTools } from '@mastra/react/hooks/tools';\nimport type { SpanRecord } from '../../types';\nimport { SpanPayloadList, SpanPayloadListName } from './span-payload-primitives';\nimport { getDelegatedToolHref, getSpanTools } from './span-payload-registry';\nimport type { SpanTool } from './span-payload-registry';\nimport { SpanPayloadSection } from './span-payload-section';\nimport type { SpanPayloadSectionProps } from './span-payload-section';\nimport { Txt } from '@/ds/components/Txt';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\n/**\n * Registered tool ids by the names a span may record them under: the tool id,\n * or the key it is registered with (what model spans pass to the provider).\n */\nfunction useRegisteredToolIds(): Map<string, string> {\n const { data: tools = {} } = useTools();\n const ids = new Map<string, string>();\n for (const [key, tool] of Object.entries(tools)) {\n ids.set(key, tool.id);\n ids.set(tool.id, tool.id);\n }\n return ids;\n}\n\nfunction SpanToolList({ tools }: { tools: SpanTool[] }) {\n const { Link, paths } = useLinkComponent();\n const registered = useRegisteredToolIds();\n\n return (\n <SpanPayloadList\n slot=\"span-tools\"\n items={tools.map(tool => {\n const registeredId = registered.get(tool.id);\n // Workspace, skill and agent-only tools are not in the registry, so they have no page to open.\n const href = getDelegatedToolHref(paths, tool.id) || (registeredId ? paths.toolLink(registeredId) : '');\n return {\n key: tool.id,\n description: tool.description,\n name: href ? (\n <Link href={href} className=\"w-fit max-w-full truncate text-foreground hover:underline\">\n <Txt as=\"span\" variant=\"label\">\n {tool.id}\n </Txt>\n </Link>\n ) : (\n <SpanPayloadListName>{tool.id}</SpanPayloadListName>\n ),\n };\n })}\n />\n );\n}\n\nexport interface SpanToolsSectionProps {\n span: SpanRecord;\n layout?: SpanPayloadSectionProps['layout'];\n}\n\n/** The tools the span offered the model. */\nexport function SpanToolsSection({ span, layout }: SpanToolsSectionProps) {\n const spanTools = getSpanTools(span);\n if (!spanTools) return null;\n\n return (\n <SpanPayloadSection\n title={`Tools (${spanTools.tools.length})`}\n icon={<ToolsIcon />}\n raw={spanTools.raw}\n layout={layout}\n >\n <SpanToolList tools={spanTools.tools} />\n </SpanPayloadSection>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAS,uBAA4C;CACnD,MAAM,EAAE,MAAM,QAAQ,CAAC,MAAM,SAAS;CACtC,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAC/C,IAAI,IAAI,KAAK,KAAK,EAAE;EACpB,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE;CAC1B;CACA,OAAO;AACT;AAEA,SAAS,aAAa,EAAE,SAAgC;CACtD,MAAM,EAAE,MAAM,UAAU,iBAAiB;CACzC,MAAM,aAAa,qBAAqB;CAExC,OACE,oBAAC,iBAAD;EACE,MAAK;EACL,OAAO,MAAM,KAAI,SAAQ;GACvB,MAAM,eAAe,WAAW,IAAI,KAAK,EAAE;GAE3C,MAAM,OAAO,qBAAqB,OAAO,KAAK,EAAE,MAAM,eAAe,MAAM,SAAS,YAAY,IAAI;GACpG,OAAO;IACL,KAAK,KAAK;IACV,aAAa,KAAK;IAClB,MAAM,OACJ,oBAAC,MAAD;KAAY;KAAM,WAAU;KAC1B,UAAA,oBAAC,KAAD;MAAK,IAAG;MAAO,SAAQ;MACpB,UAAA,KAAK;KACH,CAAA;IACD,CAAA,IAEN,oBAAC,qBAAD,EAAA,UAAsB,KAAK,GAAwB,CAAA;GAEvD;EACF,CAAC;CACF,CAAA;AAEL;;AAQA,SAAgB,iBAAiB,EAAE,MAAM,UAAiC;CACxE,MAAM,YAAY,aAAa,IAAI;CACnC,IAAI,CAAC,WAAW,OAAO;CAEvB,OACE,oBAAC,oBAAD;EACE,OAAO,UAAU,UAAU,MAAM,OAAO;EACxC,MAAM,oBAAC,WAAD,CAAY,CAAA;EAClB,KAAK,UAAU;EACP;EAER,UAAA,oBAAC,cAAD,EAAc,OAAO,UAAU,MAAQ,CAAA;CACrB,CAAA;AAExB"}
1
+ {"version":3,"file":"span-tools-section.es.js","names":["_Fragment"],"sources":["../../../../../src/domains/traces/components/span-payload/span-tools-section.tsx"],"sourcesContent":["import { useTools } from '@mastra/react/hooks/tools';\nimport { useTraceSpans } from '@mastra/react/hooks/traces';\nimport type { ReactNode } from 'react';\nimport type { SpanRecord } from '../../types';\nimport { formatSpanToolCallMessages, getRequestedToolCalls } from '../format-trace-thread-messages';\nimport { ReadOnlyToolCallProvider } from '../read-only-tool-call-provider';\nimport { SpanPayloadList, SpanPayloadListName } from './span-payload-primitives';\nimport { getDelegatedToolHref, getSpanTools } from './span-payload-registry';\nimport type { SpanTool } from './span-payload-registry';\nimport { SpanPayloadSection } from './span-payload-section';\nimport type { SpanPayloadSectionProps } from './span-payload-section';\nimport { MessageRow } from '@/domains/chat/messages/message-row';\nimport { Txt } from '@/ds/components/Txt';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { useLinkComponent } from '@/lib/framework';\n\n/**\n * Registered tool ids by the names a span may record them under: the tool id,\n * or the key it is registered with (what model spans pass to the provider).\n */\nfunction useRegisteredToolIds(): Map<string, string> {\n const { data: tools = {} } = useTools();\n const ids = new Map<string, string>();\n for (const [key, tool] of Object.entries(tools)) {\n ids.set(key, tool.id);\n ids.set(tool.id, tool.id);\n }\n return ids;\n}\n\nfunction SpanToolList({ tools }: { tools: SpanTool[] }) {\n const { Link, paths } = useLinkComponent();\n const registered = useRegisteredToolIds();\n\n return (\n <SpanPayloadList\n slot=\"span-tools\"\n items={tools.map(tool => {\n const registeredId = registered.get(tool.id);\n // Workspace, skill and agent-only tools are not in the registry, so they have no page to open.\n const href = getDelegatedToolHref(paths, tool.id) || (registeredId ? paths.toolLink(registeredId) : '');\n return {\n key: tool.id,\n description: tool.description,\n name: href ? (\n <Link href={href} className=\"w-fit max-w-full truncate text-foreground hover:underline\">\n <Txt as=\"span\" variant=\"label\">\n {tool.id}\n </Txt>\n </Link>\n ) : (\n <SpanPayloadListName>{tool.id}</SpanPayloadListName>\n ),\n };\n })}\n />\n );\n}\n\nexport interface SpanToolsSectionProps {\n span: SpanRecord;\n layout?: SpanPayloadSectionProps['layout'];\n}\n\n/**\n * The tools the model called, each opening on its input and result like in the chat,\n * then the tools the span offered the model.\n */\nexport function SpanToolsSection({ span, layout }: SpanToolsSectionProps) {\n return (\n <>\n {getRequestedToolCalls(span).length > 0 && <SpanToolCallsSection span={span} layout={layout} />}\n <SpanAvailableToolsSection span={span} layout={layout} />\n </>\n );\n}\n\nexport interface SpanToolCallsSectionProps extends SpanToolsSectionProps {\n /** Replaces the \"Tool calls\" heading, e.g. with the sentence of the notice the section sits in. */\n heading?: ReactNode;\n}\n\n/** The tools the model called, each opening on its input and the result its tool span recorded. */\nexport function SpanToolCallsSection({ span, layout, heading }: SpanToolCallsSectionProps) {\n // The results live on the tool spans, which the trace panel has usually loaded already.\n const { data } = useTraceSpans({ traceId: span.traceId, passive: true });\n const toolCalls = formatSpanToolCallMessages(span, data?.spans ?? []);\n // Only tools the chat never draws (task tools, working memory) were called; the Output JSON keeps them.\n if (toolCalls.length === 0) return null;\n\n return (\n <SpanPayloadSection\n title={`Tool calls (${toolCalls.length})`}\n heading={heading}\n icon={<ToolsIcon />}\n raw={getRequestedToolCalls(span)}\n hasPreview\n // Each call folds on its own, so the list never needs clipping.\n clip={false}\n layout={layout}\n >\n {/* Tool rows carry their own vertical margins; strip them at the edges so the card padding is the only outer spacing. */}\n <div\n data-slot=\"span-tool-calls\"\n className=\"flex flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0\"\n >\n <ReadOnlyToolCallProvider>\n {toolCalls.map(message => (\n <MessageRow key={message.id} message={message} readOnly />\n ))}\n </ReadOnlyToolCallProvider>\n </div>\n </SpanPayloadSection>\n );\n}\n\n/** The tools the span offered the model, linking to their pages when registered. */\nexport function SpanAvailableToolsSection({ span, layout }: SpanToolsSectionProps) {\n const spanTools = getSpanTools(span);\n if (!spanTools) return null;\n\n return (\n <SpanPayloadSection\n title={`Available tools (${spanTools.tools.length})`}\n icon={<ToolsIcon />}\n raw={spanTools.raw}\n layout={layout}\n >\n <SpanToolList tools={spanTools.tools} />\n </SpanPayloadSection>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,SAAS,uBAA4C;CACnD,MAAM,EAAE,MAAM,QAAQ,CAAC,MAAM,SAAS;CACtC,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAC/C,IAAI,IAAI,KAAK,KAAK,EAAE;EACpB,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE;CAC1B;CACA,OAAO;AACT;AAEA,SAAS,aAAa,EAAE,SAAgC;CACtD,MAAM,EAAE,MAAM,UAAU,iBAAiB;CACzC,MAAM,aAAa,qBAAqB;CAExC,OACE,oBAAC,iBAAD;EACE,MAAK;EACL,OAAO,MAAM,KAAI,SAAQ;GACvB,MAAM,eAAe,WAAW,IAAI,KAAK,EAAE;GAE3C,MAAM,OAAO,qBAAqB,OAAO,KAAK,EAAE,MAAM,eAAe,MAAM,SAAS,YAAY,IAAI;GACpG,OAAO;IACL,KAAK,KAAK;IACV,aAAa,KAAK;IAClB,MAAM,OACJ,oBAAC,MAAD;KAAY;KAAM,WAAU;KAC1B,UAAA,oBAAC,KAAD;MAAK,IAAG;MAAO,SAAQ;MACpB,UAAA,KAAK;KACH,CAAA;IACD,CAAA,IAEN,oBAAC,qBAAD,EAAA,UAAsB,KAAK,GAAwB,CAAA;GAEvD;EACF,CAAC;CACF,CAAA;AAEL;;;;;AAWA,SAAgB,iBAAiB,EAAE,MAAM,UAAiC;CACxE,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,sBAAsB,IAAI,CAAC,CAAC,SAAS,KAAK,oBAAC,sBAAD;EAA4B;EAAc;CAAS,CAAA,GAC9F,oBAAC,2BAAD;EAAiC;EAAc;CAAS,CAAA,CACxD,EAAA,CAAA;AAEN;;AAQA,SAAgB,qBAAqB,EAAE,MAAM,QAAQ,WAAsC;CAEzF,MAAM,EAAE,SAAS,cAAc;EAAE,SAAS,KAAK;EAAS,SAAS;CAAK,CAAC;CACvE,MAAM,YAAY,2BAA2B,MAAM,MAAM,SAAS,CAAC,CAAC;CAEpE,IAAI,UAAU,WAAW,GAAG,OAAO;CAEnC,OACE,oBAAC,oBAAD;EACE,OAAO,eAAe,UAAU,OAAO;EAC9B;EACT,MAAM,oBAAC,WAAD,CAAY,CAAA;EAClB,KAAK,sBAAsB,IAAI;EAC/B,YAAA;EAEA,MAAM;EACE;EAGR,UAAA,oBAAC,OAAD;GACE,aAAU;GACV,WAAU;GAEV,UAAA,oBAAC,0BAAD,EAAA,UACG,UAAU,KAAI,YACb,oBAAC,YAAD;IAAsC;IAAS,UAAA;GAAU,GAAxC,QAAQ,EAAgC,CAC1D,EACuB,CAAA;EACvB,CAAA;CACa,CAAA;AAExB;;AAGA,SAAgB,0BAA0B,EAAE,MAAM,UAAiC;CACjF,MAAM,YAAY,aAAa,IAAI;CACnC,IAAI,CAAC,WAAW,OAAO;CAEvB,OACE,oBAAC,oBAAD;EACE,OAAO,oBAAoB,UAAU,MAAM,OAAO;EAClD,MAAM,oBAAC,WAAD,CAAY,CAAA;EAClB,KAAK,UAAU;EACP;EAER,UAAA,oBAAC,cAAD,EAAc,OAAO,UAAU,MAAQ,CAAA;CACrB,CAAA;AAExB"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_domains_traces_components_span_payload_span_payload_json = require("./span-payload/span-payload-json.cjs.js");
3
2
  const require_domains_traces_components_span_payload_span_payload_registry = require("./span-payload/span-payload-registry.cjs.js");
3
+ const require_domains_traces_components_span_payload_span_payload_json = require("./span-payload/span-payload-json.cjs.js");
4
4
  const require_domains_traces_components_span_payload_span_payload_messages = require("./span-payload/span-payload-messages.cjs.js");
5
5
  const require_domains_traces_components_span_payload_span_payload_processor = require("./span-payload/span-payload-processor.cjs.js");
6
6
  const require_domains_traces_components_span_payload_span_input_renderers = require("./span-payload/span-input-renderers.cjs.js");
@@ -8,13 +8,18 @@ const require_domains_traces_components_span_payload_span_output_renderers = req
8
8
  const require_domains_traces_components_span_payload_span_error_renderer = require("./span-payload/span-error-renderer.cjs.js");
9
9
  const require_domains_traces_components_span_payload_span_payload_section = require("./span-payload/span-payload-section.cjs.js");
10
10
  const require_domains_traces_components_span_payload_span_processor_attributes = require("./span-payload/span-processor-attributes.cjs.js");
11
+ const require_domains_traces_components_span_payload_span_processor_mutations = require("./span-payload/span-processor-mutations.cjs.js");
12
+ exports.SpanErrorDetails = require_domains_traces_components_span_payload_span_error_renderer.SpanErrorDetails;
11
13
  exports.SpanErrorRenderer = require_domains_traces_components_span_payload_span_error_renderer.SpanErrorRenderer;
12
14
  exports.SpanInputRenderer = require_domains_traces_components_span_payload_span_input_renderers.SpanInputRenderer;
13
15
  exports.SpanOutputRenderer = require_domains_traces_components_span_payload_span_output_renderers.SpanOutputRenderer;
14
16
  exports.SpanPayloadJson = require_domains_traces_components_span_payload_span_payload_json.SpanPayloadJson;
17
+ exports.SpanPayloadJsonSection = require_domains_traces_components_span_payload_span_payload_section.SpanPayloadJsonSection;
15
18
  exports.SpanPayloadMessages = require_domains_traces_components_span_payload_span_payload_messages.SpanPayloadMessages;
16
19
  exports.SpanPayloadProcessor = require_domains_traces_components_span_payload_span_payload_processor.SpanPayloadProcessor;
17
20
  exports.SpanPayloadSection = require_domains_traces_components_span_payload_span_payload_section.SpanPayloadSection;
18
21
  exports.SpanProcessorAttributes = require_domains_traces_components_span_payload_span_processor_attributes.SpanProcessorAttributes;
22
+ exports.SpanProcessorMutations = require_domains_traces_components_span_payload_span_processor_mutations.SpanProcessorMutations;
19
23
  exports.getSpanOutputPayload = require_domains_traces_components_span_payload_span_payload_registry.getSpanOutputPayload;
20
24
  exports.hasSpanInputPreview = require_domains_traces_components_span_payload_span_payload_registry.hasSpanInputPreview;
25
+ exports.hasSpanOutputPreview = require_domains_traces_components_span_payload_span_payload_registry.hasSpanOutputPreview;
@@ -1,10 +1,11 @@
1
+ import { getSpanOutputPayload, hasSpanInputPreview, hasSpanOutputPreview } from "./span-payload/span-payload-registry.es.js";
1
2
  import { SpanPayloadJson } from "./span-payload/span-payload-json.es.js";
2
- import { getSpanOutputPayload, hasSpanInputPreview } from "./span-payload/span-payload-registry.es.js";
3
3
  import { SpanPayloadMessages } from "./span-payload/span-payload-messages.es.js";
4
4
  import { SpanPayloadProcessor } from "./span-payload/span-payload-processor.es.js";
5
5
  import { SpanInputRenderer } from "./span-payload/span-input-renderers.es.js";
6
6
  import { SpanOutputRenderer } from "./span-payload/span-output-renderers.es.js";
7
- import { SpanErrorRenderer } from "./span-payload/span-error-renderer.es.js";
8
- import { SpanPayloadSection } from "./span-payload/span-payload-section.es.js";
7
+ import { SpanErrorDetails, SpanErrorRenderer } from "./span-payload/span-error-renderer.es.js";
8
+ import { SpanPayloadJsonSection, SpanPayloadSection } from "./span-payload/span-payload-section.es.js";
9
9
  import { SpanProcessorAttributes } from "./span-payload/span-processor-attributes.es.js";
10
- export { SpanErrorRenderer, SpanInputRenderer, SpanOutputRenderer, SpanPayloadJson, SpanPayloadMessages, SpanPayloadProcessor, SpanPayloadSection, SpanProcessorAttributes, getSpanOutputPayload, hasSpanInputPreview };
10
+ import { SpanProcessorMutations } from "./span-payload/span-processor-mutations.es.js";
11
+ export { SpanErrorDetails, SpanErrorRenderer, SpanInputRenderer, SpanOutputRenderer, SpanPayloadJson, SpanPayloadJsonSection, SpanPayloadMessages, SpanPayloadProcessor, SpanPayloadSection, SpanProcessorAttributes, SpanProcessorMutations, getSpanOutputPayload, hasSpanInputPreview, hasSpanOutputPreview };
@@ -2,10 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_utils = require("../../../../utils-uDc1ofX1.cjs");
3
3
  const require_Button = require("../../../../Button-YQRflC47.cjs");
4
4
  const require_components_CollapsibleBox = require("../../../../components/CollapsibleBox.cjs.js");
5
+ const require_domains_traces_components_format_hierarchical_spans = require("../format-hierarchical-spans.cjs.js");
5
6
  const require_domains_traces_components_thread_trace_thread_trace_row_context = require("./thread-trace-row-context.cjs.js");
6
7
  const require_domains_traces_components_thread_trace_thread_trace_context = require("./thread-trace-context.cjs.js");
7
8
  const require_domains_traces_hooks_use_expanded_span_ids = require("../../hooks/use-expanded-span-ids.cjs.js");
8
- const require_domains_traces_components_format_hierarchical_spans = require("../format-hierarchical-spans.cjs.js");
9
9
  const require_domains_traces_components_trace_span_tree = require("../trace-span-tree.cjs.js");
10
10
  let react = require("react");
11
11
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,10 +1,10 @@
1
1
  import { t as cn } from "../../../../utils-DQx8TpNT.js";
2
2
  import { t as Button } from "../../../../Button-Bw1e3ONi.js";
3
3
  import { CollapsibleBox } from "../../../../components/CollapsibleBox.es.js";
4
+ import { formatHierarchicalSpans } from "../format-hierarchical-spans.es.js";
4
5
  import { useThreadTraceRow } from "./thread-trace-row-context.es.js";
5
6
  import { useThreadTrace } from "./thread-trace-context.es.js";
6
7
  import { useExpandedSpanIds } from "../../hooks/use-expanded-span-ids.es.js";
7
- import { formatHierarchicalSpans } from "../format-hierarchical-spans.es.js";
8
8
  import { TraceSpanTree } from "../trace-span-tree.es.js";
9
9
  import { useMemo } from "react";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -9,9 +9,9 @@ const require_Notice = require("../../../Notice-DWNeCe-t.cjs");
9
9
  const require_components_Skeleton = require("../../../components/Skeleton.cjs.js");
10
10
  const require_DataPanel = require("../../../DataPanel-Ded_OhrA.cjs");
11
11
  const require_components_SearchInput = require("../../../components/SearchInput.cjs.js");
12
+ const require_domains_traces_components_format_hierarchical_spans = require("./format-hierarchical-spans.cjs.js");
12
13
  const require_resize_separator = require("../../../resize/separator.cjs.js");
13
14
  const require_domains_traces_hooks_get_all_span_ids = require("../hooks/get-all-span-ids.cjs.js");
14
- const require_domains_traces_components_format_hierarchical_spans = require("./format-hierarchical-spans.cjs.js");
15
15
  const require_domains_traces_components_trace_span_tree = require("./trace-span-tree.cjs.js");
16
16
  const require_domains_traces_components_trace_span_timeline = require("./trace-span-timeline.cjs.js");
17
17
  const require_domains_traces_hooks_use_download_trace_json = require("../hooks/use-download-trace-json.cjs.js");
@@ -8,9 +8,9 @@ import { t as Notice } from "../../../Notice-CyKngbbv.js";
8
8
  import { Skeleton } from "../../../components/Skeleton.es.js";
9
9
  import { t as DataPanel } from "../../../DataPanel-CfLkwH2X.js";
10
10
  import { SearchInput } from "../../../components/SearchInput.es.js";
11
+ import { formatHierarchicalSpans } from "./format-hierarchical-spans.es.js";
11
12
  import { PanelSeparator } from "../../../resize/separator.es.js";
12
13
  import { getAllSpanIds } from "../hooks/get-all-span-ids.es.js";
13
- import { formatHierarchicalSpans } from "./format-hierarchical-spans.es.js";
14
14
  import { TraceSpanTree } from "./trace-span-tree.es.js";
15
15
  import { TraceSpanTimeline } from "./trace-span-timeline.es.js";
16
16
  import { useDownloadTraceJson } from "../hooks/use-download-trace-json.es.js";
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_domains_traces_components_format_hierarchical_spans = require("./format-hierarchical-spans.cjs.js");
2
3
  const require_domains_traces_components_trace_id_button = require("./trace-id-button.cjs.js");
3
4
  const require_domains_traces_hooks_get_all_span_ids = require("../hooks/get-all-span-ids.cjs.js");
4
- const require_domains_traces_components_format_hierarchical_spans = require("./format-hierarchical-spans.cjs.js");
5
5
  const require_domains_traces_components_trace_span_tree = require("./trace-span-tree.cjs.js");
6
6
  const require_DataDetailsPanel = require("../../../DataDetailsPanel-Dg_iUJ6L.cjs");
7
7
  let react = require("react");
@@ -1,6 +1,6 @@
1
+ import { formatHierarchicalSpans } from "./format-hierarchical-spans.es.js";
1
2
  import { TraceIdButton } from "./trace-id-button.es.js";
2
3
  import { getAllSpanIds } from "../hooks/get-all-span-ids.es.js";
3
- import { formatHierarchicalSpans } from "./format-hierarchical-spans.es.js";
4
4
  import { TraceSpanTree } from "./trace-span-tree.es.js";
5
5
  import { t as DataDetailsPanel } from "../../../DataDetailsPanel-CvAIsV60.js";
6
6
  import { useEffect, useMemo, useState } from "react";
@@ -2,16 +2,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_utils = require("../../../utils-uDc1ofX1.cjs");
3
3
  const require_Button = require("../../../Button-YQRflC47.cjs");
4
4
  const require_Txt = require("../../../Txt-BnoSqxKE.cjs");
5
- const require_domains_chat_context_tool_call_context = require("../../chat/context/tool-call-context.cjs.js");
6
5
  const require_domains_chat_messages_message_row = require("../../chat/messages/message-row.cjs.js");
6
+ const require_domains_traces_components_format_trace_thread_messages = require("./format-trace-thread-messages.cjs.js");
7
+ const require_domains_traces_components_read_only_tool_call_provider = require("./read-only-tool-call-provider.cjs.js");
7
8
  const require_domains_traces_components_traces_error_content = require("./traces-error-content.cjs.js");
8
9
  const require_domains_traces_components_trace_messages_skeleton = require("./trace-messages-skeleton.cjs.js");
9
- const require_domains_traces_components_format_trace_thread_messages = require("./format-trace-thread-messages.cjs.js");
10
10
  let react_jsx_runtime = require("react/jsx-runtime");
11
11
  let lucide_react = require("lucide-react");
12
12
  let _mastra_react_hooks_traces = require("@mastra/react/hooks/traces");
13
13
  // src/domains/traces/components/trace-thread-item-view.tsx
14
- var noop = () => {};
15
14
  function TraceThreadItemView({ traceId, onHighlightSpans, className }) {
16
15
  const { data, isLoading, error } = (0, _mastra_react_hooks_traces.useTraceSpans)({
17
16
  traceId,
@@ -40,43 +39,32 @@ function TraceThreadItemView({ traceId, onHighlightSpans, className }) {
40
39
  className: require_utils.cn("min-w-0 p-4", className),
41
40
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
42
41
  className: "mx-auto flex w-full max-w-3xl flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0",
43
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_context_tool_call_context.ToolCallProvider, {
44
- approveToolcall: noop,
45
- declineToolcall: noop,
46
- approveToolcallGenerate: noop,
47
- declineToolcallGenerate: noop,
48
- approveNetworkToolcall: noop,
49
- declineNetworkToolcall: noop,
50
- isRunning: false,
51
- toolCallApprovals: {},
52
- networkToolCallApprovals: {},
53
- children: messages.map((message) => {
54
- const action = onHighlightSpans && message.traceSpanIds.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Button.Button, {
55
- variant: "ghost",
56
- size: "icon-sm",
57
- tooltip: "Highlight spans",
58
- "aria-label": "Highlight spans",
59
- onClick: () => onHighlightSpans(message.traceSpanIds),
60
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ListTreeIcon, {})
61
- }) : void 0;
62
- if (message.content.parts.every((part) => part.type === "tool-invocation") && action) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
63
- className: "group/tool mb-3 flex items-start gap-1 last:mb-0",
64
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_messages_message_row.MessageRow, {
65
- message,
66
- readOnly: true,
67
- className: "flex-1"
68
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
69
- className: "shrink-0 group-focus-within/tool:opacity-100 group-hover/tool:opacity-100 motion-safe:transition-opacity pointer-fine:opacity-0",
70
- children: action
71
- })]
72
- }, message.id);
73
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_messages_message_row.MessageRow, {
42
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_traces_components_read_only_tool_call_provider.ReadOnlyToolCallProvider, { children: messages.map((message) => {
43
+ const action = onHighlightSpans && message.traceSpanIds.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Button.Button, {
44
+ variant: "ghost",
45
+ size: "icon-sm",
46
+ tooltip: "Highlight spans",
47
+ "aria-label": "Highlight spans",
48
+ onClick: () => onHighlightSpans(message.traceSpanIds),
49
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ListTreeIcon, {})
50
+ }) : void 0;
51
+ if (message.content.parts.every((part) => part.type === "tool-invocation") && action) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52
+ className: "group/tool mb-3 flex items-start gap-1 last:mb-0",
53
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_messages_message_row.MessageRow, {
74
54
  message,
75
55
  readOnly: true,
76
- footer: action
77
- }, message.id);
78
- })
79
- })
56
+ className: "flex-1"
57
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
58
+ className: "shrink-0 group-focus-within/tool:opacity-100 group-hover/tool:opacity-100 motion-safe:transition-opacity pointer-fine:opacity-0",
59
+ children: action
60
+ })]
61
+ }, message.id);
62
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_chat_messages_message_row.MessageRow, {
63
+ message,
64
+ readOnly: true,
65
+ footer: action
66
+ }, message.id);
67
+ }) })
80
68
  })
81
69
  });
82
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"trace-thread-item-view.cjs.js","names":["useTraceSpans","TraceMessagesSkeleton","TracesErrorContent","formatTraceThreadMessages","Txt","cn","ToolCallProvider","Button","ListTreeIcon","MessageRow"],"sources":["../../../../src/domains/traces/components/trace-thread-item-view.tsx"],"sourcesContent":["import { useTraceSpans } from '@mastra/react/hooks/traces';\nimport { ListTreeIcon } from 'lucide-react';\nimport { formatTraceThreadMessages } from './format-trace-thread-messages';\nimport { TraceMessagesSkeleton } from './trace-messages-skeleton';\nimport { ToolCallProvider } from '@/domains/chat/context/tool-call-context';\nimport { MessageRow } from '@/domains/chat/messages/message-row';\nimport { TracesErrorContent } from '@/domains/traces/components/traces-error-content';\nimport { Button } from '@/ds/components/Button';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/utils/cn';\n\nexport interface TraceThreadItemViewProps {\n traceId: string;\n /** Called with the ids of the spans behind a message (text or tool call) when its \"Highlight spans\" action is clicked. */\n onHighlightSpans?: (spanIds: string[]) => void;\n className?: string;\n}\n\nconst noop = () => {};\n\nexport function TraceThreadItemView({ traceId, onHighlightSpans, className }: TraceThreadItemViewProps) {\n const { data, isLoading, error } = useTraceSpans({\n traceId: traceId,\n passive: true,\n queryOptions: { enabled: !!traceId },\n });\n\n if (isLoading) return <TraceMessagesSkeleton className={className} />;\n\n if (error) {\n return (\n <div className=\"flex h-full items-center justify-center p-4\">\n <TracesErrorContent error={error} resource=\"trace\" errorTitle=\"Failed to load partial thread\" />\n </div>\n );\n }\n\n const messages = data ? formatTraceThreadMessages(data.spans) : [];\n\n if (messages.length === 0) {\n return (\n <div className=\"flex h-full items-center justify-center p-4\">\n <Txt variant=\"body\" tone=\"muted\">\n No agent turn found for this trace.\n </Txt>\n </div>\n );\n }\n\n return (\n <div className={cn('min-w-0 p-4', className)}>\n {/* Messages carry their own vertical margins; strip them at the edges so `p-4` is the only outer spacing. */}\n <div className=\"mx-auto flex w-full max-w-3xl flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0\">\n <ToolCallProvider\n approveToolcall={noop}\n declineToolcall={noop}\n approveToolcallGenerate={noop}\n declineToolcallGenerate={noop}\n approveNetworkToolcall={noop}\n declineNetworkToolcall={noop}\n isRunning={false}\n toolCallApprovals={{}}\n networkToolCallApprovals={{}}\n >\n {messages.map(message => {\n const action =\n onHighlightSpans && message.traceSpanIds.length > 0 ? (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n tooltip=\"Highlight spans\"\n aria-label=\"Highlight spans\"\n onClick={() => onHighlightSpans(message.traceSpanIds)}\n >\n <ListTreeIcon />\n </Button>\n ) : undefined;\n\n const isToolCall = message.content.parts.every(part => part.type === 'tool-invocation');\n if (isToolCall && action) {\n // Tool calls sit on one line, so the action goes beside the tool card instead of below it.\n return (\n <div key={message.id} className=\"group/tool mb-3 flex items-start gap-1 last:mb-0\">\n <MessageRow message={message} readOnly className=\"flex-1\" />\n <div className=\"shrink-0 group-focus-within/tool:opacity-100 group-hover/tool:opacity-100 motion-safe:transition-opacity pointer-fine:opacity-0\">\n {action}\n </div>\n </div>\n );\n }\n\n return <MessageRow key={message.id} message={message} readOnly footer={action} />;\n })}\n </ToolCallProvider>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAM,aAAa,CAAC;AAEpB,SAAgB,oBAAoB,EAAE,SAAS,kBAAkB,aAAuC;CACtG,MAAM,EAAE,MAAM,WAAW,WAAA,GAAUA,2BAAAA,cAAAA,CAAc;EACtC;EACT,SAAS;EACT,cAAc,EAAE,SAAS,CAAC,CAAC,QAAQ;CACrC,CAAC;CAED,IAAI,WAAW,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,0DAAAA,uBAAD,EAAkC,UAAY,CAAA;CAEpE,IAAI,OACF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,uDAAAA,oBAAD;GAA2B;GAAO,UAAS;GAAQ,YAAW;EAAiC,CAAA;CAC5F,CAAA;CAIT,MAAM,WAAW,OAAOC,+DAAAA,0BAA0B,KAAK,KAAK,IAAI,CAAC;CAEjE,IAAI,SAAS,WAAW,GACtB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,YAAAA,KAAD;GAAK,SAAQ;GAAO,MAAK;GAAQ,UAAA;EAE5B,CAAA;CACF,CAAA;CAIT,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,eAAe,SAAS;EAEzC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,+CAAAA,kBAAD;IACE,iBAAiB;IACjB,iBAAiB;IACjB,yBAAyB;IACzB,yBAAyB;IACzB,wBAAwB;IACxB,wBAAwB;IACxB,WAAW;IACX,mBAAmB,CAAC;IACpB,0BAA0B,CAAC;IAE1B,UAAA,SAAS,KAAI,YAAW;KACvB,MAAM,SACJ,oBAAoB,QAAQ,aAAa,SAAS,IAChD,iBAAA,GAAA,kBAAA,IAAA,CAACC,eAAAA,QAAD;MACE,SAAQ;MACR,MAAK;MACL,SAAQ;MACR,cAAW;MACX,eAAe,iBAAiB,QAAQ,YAAY;MAEpD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,cAAD,CAAe,CAAA;KACT,CAAA,IACN,KAAA;KAGN,IADmB,QAAQ,QAAQ,MAAM,OAAM,SAAQ,KAAK,SAAS,iBACjE,KAAc,QAEhB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAsB,WAAU;MAAhC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,0CAAAA,YAAD;OAAqB;OAAS,UAAA;OAAS,WAAU;MAAU,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAU;OACZ,UAAA;MACE,CAAA,CACF;KALK,GAAA,QAAQ,EAKb;KAIT,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,0CAAAA,YAAD;MAAsC;MAAS,UAAA;MAAS,QAAQ;KAAS,GAAxD,QAAQ,EAAgD;IAClF,CAAC;GACe,CAAA;EACf,CAAA;CACF,CAAA;AAET"}
1
+ {"version":3,"file":"trace-thread-item-view.cjs.js","names":["useTraceSpans","TraceMessagesSkeleton","TracesErrorContent","formatTraceThreadMessages","Txt","cn","ReadOnlyToolCallProvider","Button","ListTreeIcon","MessageRow"],"sources":["../../../../src/domains/traces/components/trace-thread-item-view.tsx"],"sourcesContent":["import { useTraceSpans } from '@mastra/react/hooks/traces';\nimport { ListTreeIcon } from 'lucide-react';\nimport { formatTraceThreadMessages } from './format-trace-thread-messages';\nimport { ReadOnlyToolCallProvider } from './read-only-tool-call-provider';\nimport { TraceMessagesSkeleton } from './trace-messages-skeleton';\nimport { MessageRow } from '@/domains/chat/messages/message-row';\nimport { TracesErrorContent } from '@/domains/traces/components/traces-error-content';\nimport { Button } from '@/ds/components/Button';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/utils/cn';\n\nexport interface TraceThreadItemViewProps {\n traceId: string;\n /** Called with the ids of the spans behind a message (text or tool call) when its \"Highlight spans\" action is clicked. */\n onHighlightSpans?: (spanIds: string[]) => void;\n className?: string;\n}\n\nexport function TraceThreadItemView({ traceId, onHighlightSpans, className }: TraceThreadItemViewProps) {\n const { data, isLoading, error } = useTraceSpans({\n traceId: traceId,\n passive: true,\n queryOptions: { enabled: !!traceId },\n });\n\n if (isLoading) return <TraceMessagesSkeleton className={className} />;\n\n if (error) {\n return (\n <div className=\"flex h-full items-center justify-center p-4\">\n <TracesErrorContent error={error} resource=\"trace\" errorTitle=\"Failed to load partial thread\" />\n </div>\n );\n }\n\n const messages = data ? formatTraceThreadMessages(data.spans) : [];\n\n if (messages.length === 0) {\n return (\n <div className=\"flex h-full items-center justify-center p-4\">\n <Txt variant=\"body\" tone=\"muted\">\n No agent turn found for this trace.\n </Txt>\n </div>\n );\n }\n\n return (\n <div className={cn('min-w-0 p-4', className)}>\n {/* Messages carry their own vertical margins; strip them at the edges so `p-4` is the only outer spacing. */}\n <div className=\"mx-auto flex w-full max-w-3xl flex-col [&>[data-slot=message]:first-child]:mt-0 [&>[data-slot=message]:last-child]:mb-0\">\n <ReadOnlyToolCallProvider>\n {messages.map(message => {\n const action =\n onHighlightSpans && message.traceSpanIds.length > 0 ? (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n tooltip=\"Highlight spans\"\n aria-label=\"Highlight spans\"\n onClick={() => onHighlightSpans(message.traceSpanIds)}\n >\n <ListTreeIcon />\n </Button>\n ) : undefined;\n\n const isToolCall = message.content.parts.every(part => part.type === 'tool-invocation');\n if (isToolCall && action) {\n // Tool calls sit on one line, so the action goes beside the tool card instead of below it.\n return (\n <div key={message.id} className=\"group/tool mb-3 flex items-start gap-1 last:mb-0\">\n <MessageRow message={message} readOnly className=\"flex-1\" />\n <div className=\"shrink-0 group-focus-within/tool:opacity-100 group-hover/tool:opacity-100 motion-safe:transition-opacity pointer-fine:opacity-0\">\n {action}\n </div>\n </div>\n );\n }\n\n return <MessageRow key={message.id} message={message} readOnly footer={action} />;\n })}\n </ReadOnlyToolCallProvider>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,SAAgB,oBAAoB,EAAE,SAAS,kBAAkB,aAAuC;CACtG,MAAM,EAAE,MAAM,WAAW,WAAA,GAAUA,2BAAAA,cAAAA,CAAc;EACtC;EACT,SAAS;EACT,cAAc,EAAE,SAAS,CAAC,CAAC,QAAQ;CACrC,CAAC;CAED,IAAI,WAAW,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,0DAAAA,uBAAD,EAAkC,UAAY,CAAA;CAEpE,IAAI,OACF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,uDAAAA,oBAAD;GAA2B;GAAO,UAAS;GAAQ,YAAW;EAAiC,CAAA;CAC5F,CAAA;CAIT,MAAM,WAAW,OAAOC,+DAAAA,0BAA0B,KAAK,KAAK,IAAI,CAAC;CAEjE,IAAI,SAAS,WAAW,GACtB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,YAAAA,KAAD;GAAK,SAAQ;GAAO,MAAK;GAAQ,UAAA;EAE5B,CAAA;CACF,CAAA;CAIT,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,eAAe,SAAS;EAEzC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,+DAAAA,0BAAD,EAAA,UACG,SAAS,KAAI,YAAW;IACvB,MAAM,SACJ,oBAAoB,QAAQ,aAAa,SAAS,IAChD,iBAAA,GAAA,kBAAA,IAAA,CAACC,eAAAA,QAAD;KACE,SAAQ;KACR,MAAK;KACL,SAAQ;KACR,cAAW;KACX,eAAe,iBAAiB,QAAQ,YAAY;KAEpD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,cAAD,CAAe,CAAA;IACT,CAAA,IACN,KAAA;IAGN,IADmB,QAAQ,QAAQ,MAAM,OAAM,SAAQ,KAAK,SAAS,iBACjE,KAAc,QAEhB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAsB,WAAU;KAAhC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,0CAAAA,YAAD;MAAqB;MAAS,UAAA;MAAS,WAAU;KAAU,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAU;MACZ,UAAA;KACE,CAAA,CACF;IALK,GAAA,QAAQ,EAKb;IAIT,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,0CAAAA,YAAD;KAAsC;KAAS,UAAA;KAAS,QAAQ;IAAS,GAAxD,QAAQ,EAAgD;GAClF,CAAC,EACuB,CAAA;EACvB,CAAA;CACF,CAAA;AAET"}