@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.11

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 (112) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/README.md +23 -8
  3. package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-CHDVZHHK.js} +38 -23
  4. package/dist/AgentCodeSnippets-CHDVZHHK.js.map +1 -0
  5. package/dist/AgentMetricChart-6RGWFMJE.js +15 -0
  6. package/dist/AgentOverview-3LJZ6MO7.js +311 -0
  7. package/dist/AgentOverview-3LJZ6MO7.js.map +1 -0
  8. package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-5GOJKT7D.js} +19 -10
  9. package/dist/AgentSessionEventTimeline-5GOJKT7D.js.map +1 -0
  10. package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-UYG3JQMP.js} +144 -57
  11. package/dist/AgentSessionEventTimelineChart-UYG3JQMP.js.map +1 -0
  12. package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-KUABCQ4W.js} +140 -27
  13. package/dist/AgentSessions-KUABCQ4W.js.map +1 -0
  14. package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-PED5C2P7.js} +162 -126
  15. package/dist/ConnectorSettings-PED5C2P7.js.map +1 -0
  16. package/dist/{DockLayout-LM4AFMFY.js → DockLayout-ACM7BVIH.js} +10 -10
  17. package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-SGBYRKHI.js} +14 -12
  18. package/dist/DrawerLayout-SGBYRKHI.js.map +1 -0
  19. package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-GJTVFXFY.js} +22 -28
  20. package/dist/ModelSettings-GJTVFXFY.js.map +1 -0
  21. package/dist/OpenUiFenceBlock-MJTC2VJ5.js +9 -0
  22. package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-VETQ7UPE.js} +17 -21
  23. package/dist/SandboxSettings-VETQ7UPE.js.map +1 -0
  24. package/dist/SchedulesPage-LHJ3U2VM.js +15 -0
  25. package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-5ZCU66FF.js} +9 -9
  26. package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-5ZCU66FF.js.map} +1 -1
  27. package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-SJXFKUAJ.js} +171 -26
  28. package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
  29. package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-TR5CAB6Q.js} +80 -58
  30. package/dist/SidebarLayout-TR5CAB6Q.js.map +1 -0
  31. package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-TRTY2YH3.js} +24 -22
  32. package/dist/SkillSettings-TRTY2YH3.js.map +1 -0
  33. package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-GZUSRZIR.js} +9 -9
  34. package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-2TM6I4LJ.js} +10 -10
  35. package/dist/{chunk-U7KURWW3.js → chunk-2GIZY3JJ.js} +276 -54
  36. package/dist/chunk-2GIZY3JJ.js.map +1 -0
  37. package/dist/{chunk-ZKNUMH2M.js → chunk-2MUK3SMR.js} +13 -11
  38. package/dist/chunk-2MUK3SMR.js.map +1 -0
  39. package/dist/{chunk-WVE3F724.js → chunk-2QTH6JHX.js} +21 -4
  40. package/dist/chunk-2QTH6JHX.js.map +1 -0
  41. package/dist/{chunk-XAU7QFG3.js → chunk-5N5V7YLO.js} +72 -256
  42. package/dist/chunk-5N5V7YLO.js.map +1 -0
  43. package/dist/{chunk-CYHJDKFB.js → chunk-75YEQUUD.js} +189 -52
  44. package/dist/chunk-75YEQUUD.js.map +1 -0
  45. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  46. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  47. package/dist/{chunk-M62XY4NC.js → chunk-BXG6XN2S.js} +235 -108
  48. package/dist/chunk-BXG6XN2S.js.map +1 -0
  49. package/dist/chunk-GKXDRULM.js +587 -0
  50. package/dist/chunk-GKXDRULM.js.map +1 -0
  51. package/dist/{chunk-ZTMKFZQ3.js → chunk-OH357IHR.js} +5572 -3367
  52. package/dist/chunk-OH357IHR.js.map +1 -0
  53. package/dist/{chunk-DMMZSZTN.js → chunk-P6MZDITS.js} +60 -16
  54. package/dist/chunk-P6MZDITS.js.map +1 -0
  55. package/dist/{chunk-MPNSO7E6.js → chunk-SLMFEG7X.js} +2 -2
  56. package/dist/chunk-T6QQV5LK.js +238 -0
  57. package/dist/chunk-T6QQV5LK.js.map +1 -0
  58. package/dist/{chunk-6O6FWUDW.js → chunk-UWLL327M.js} +641 -388
  59. package/dist/chunk-UWLL327M.js.map +1 -0
  60. package/dist/{chunk-FJW36PD7.js → chunk-VAOCM3QQ.js} +28 -24
  61. package/dist/chunk-VAOCM3QQ.js.map +1 -0
  62. package/dist/chunk-Y7O6CMC7.js +517 -0
  63. package/dist/chunk-Y7O6CMC7.js.map +1 -0
  64. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  65. package/dist/index.d.ts +377 -108
  66. package/dist/index.js +69 -488
  67. package/dist/index.js.map +1 -1
  68. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +49 -14
  69. package/dist/plugins/trueforge-agent-server-adapter/index.js +161 -60
  70. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  71. package/dist/styles.css +1 -1
  72. package/package.json +5 -4
  73. package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
  74. package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
  75. package/dist/AgentOverview-EEBHJC32.js +0 -167
  76. package/dist/AgentOverview-EEBHJC32.js.map +0 -1
  77. package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
  78. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
  79. package/dist/AgentSessions-3MPDZASK.js.map +0 -1
  80. package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
  81. package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
  82. package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
  83. package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
  84. package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
  85. package/dist/SchedulesPage-KKLUDO6B.js +0 -15
  86. package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
  87. package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
  88. package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
  89. package/dist/chunk-2XPPBEYF.js +0 -74
  90. package/dist/chunk-2XPPBEYF.js.map +0 -1
  91. package/dist/chunk-6O6FWUDW.js.map +0 -1
  92. package/dist/chunk-7Z2C2K7F.js +0 -578
  93. package/dist/chunk-7Z2C2K7F.js.map +0 -1
  94. package/dist/chunk-CYHJDKFB.js.map +0 -1
  95. package/dist/chunk-DMMZSZTN.js.map +0 -1
  96. package/dist/chunk-FJW36PD7.js.map +0 -1
  97. package/dist/chunk-M62XY4NC.js.map +0 -1
  98. package/dist/chunk-QC42MLAK.js.map +0 -1
  99. package/dist/chunk-SFZNIO6U.js +0 -18
  100. package/dist/chunk-SFZNIO6U.js.map +0 -1
  101. package/dist/chunk-U7KURWW3.js.map +0 -1
  102. package/dist/chunk-WVE3F724.js.map +0 -1
  103. package/dist/chunk-XAU7QFG3.js.map +0 -1
  104. package/dist/chunk-ZKNUMH2M.js.map +0 -1
  105. package/dist/chunk-ZTMKFZQ3.js.map +0 -1
  106. /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-6RGWFMJE.js.map} +0 -0
  107. /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-ACM7BVIH.js.map} +0 -0
  108. /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-MJTC2VJ5.js.map} +0 -0
  109. /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-LHJ3U2VM.js.map} +0 -0
  110. /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-GZUSRZIR.js.map} +0 -0
  111. /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-2TM6I4LJ.js.map} +0 -0
  112. /package/dist/{chunk-MPNSO7E6.js.map → chunk-SLMFEG7X.js.map} +0 -0
@@ -0,0 +1,311 @@
1
+ "use client";
2
+ import {
3
+ TOOL_TAG_ALL,
4
+ Tooltip,
5
+ approvalSelectorsFromMount,
6
+ disableSelectorsFromMount,
7
+ editableMountsFromSpec,
8
+ enableSelectorsFromMount,
9
+ mcpToolKind,
10
+ namedToolRequiresApproval,
11
+ selectedToolNames,
12
+ useSlot
13
+ } from "./chunk-OH357IHR.js";
14
+ import "./chunk-T6QQV5LK.js";
15
+ import {
16
+ Icon
17
+ } from "./chunk-5N5V7YLO.js";
18
+ import {
19
+ useOptionalServer
20
+ } from "./chunk-2GIZY3JJ.js";
21
+ import "./chunk-M6MHLVSO.js";
22
+ import "./chunk-SLMFEG7X.js";
23
+ import {
24
+ cn
25
+ } from "./chunk-GKXDRULM.js";
26
+
27
+ // src/atoms/agent-details/AgentOverview.tsx
28
+ import { useState as useState2 } from "react";
29
+
30
+ // src/atoms/agent-details/AgentOverviewMcpServers.tsx
31
+ import { useEffect, useMemo, useState } from "react";
32
+ import { jsx, jsxs } from "react/jsx-runtime";
33
+ var KIND_CLASSES = {
34
+ read: "border-border bg-secondary-bg text-text-secondary",
35
+ write: "border-border bg-secondary-bg text-text-primary",
36
+ destructive: "border-failure-bg/30 bg-failure-bg/10 text-failure-bg"
37
+ };
38
+ var KIND_ORDER = {
39
+ read: 0,
40
+ write: 1,
41
+ unknown: 2,
42
+ destructive: 3
43
+ };
44
+ function toolCountLabel(count) {
45
+ return count === 1 ? "1 tool" : `${count} tools`;
46
+ }
47
+ function toolSelectorLabel(enableSelectors) {
48
+ if (enableSelectors.includes(TOOL_TAG_ALL)) return "All tools";
49
+ return enableSelectors.filter((selector) => selector.startsWith("@")).join(" ");
50
+ }
51
+ function ApprovalCountBadge({ count }) {
52
+ return /* @__PURE__ */ jsxs(
53
+ "span",
54
+ {
55
+ className: "border-warning-bg/40 bg-warning-bg/10 text-warning-bg inline-flex shrink-0 items-center gap-1 rounded-full border px-1.5 py-0.5 text-[0.625rem] font-medium",
56
+ "aria-label": `${count} ${count === 1 ? "tool needs" : "tools need"} approval`,
57
+ children: [
58
+ /* @__PURE__ */ jsx(Icon, { name: "shield-check", className: "size-2.5" }),
59
+ count
60
+ ]
61
+ }
62
+ );
63
+ }
64
+ function ToolKindPill({ kind }) {
65
+ return /* @__PURE__ */ jsx("span", { className: cn("shrink-0 rounded-full border px-1.5 py-0.5 text-[0.625rem] font-medium", KIND_CLASSES[kind]), children: kind });
66
+ }
67
+ function ApprovalIndicator({ approvalRequired, toolName }) {
68
+ return /* @__PURE__ */ jsx(
69
+ Tooltip,
70
+ {
71
+ content: approvalRequired ? "Asks for approval before running" : "Runs without asking for approval",
72
+ triggerClassName: "shrink-0",
73
+ children: /* @__PURE__ */ jsx(
74
+ "span",
75
+ {
76
+ role: "img",
77
+ "aria-label": `${toolName} ${approvalRequired ? "requires approval" : "runs without approval"}`,
78
+ className: cn(
79
+ "flex size-5 items-center justify-center rounded-md border",
80
+ approvalRequired ? "border-warning-bg/50 bg-warning-bg/10 text-warning-bg" : "border-border text-text-secondary"
81
+ ),
82
+ children: /* @__PURE__ */ jsx(Icon, { name: approvalRequired ? "shield-check" : "shield", className: "size-3" })
83
+ }
84
+ )
85
+ }
86
+ );
87
+ }
88
+ function AgentOverviewMcpServers({ mcpServers }) {
89
+ const AgentOverviewCard = useSlot("AgentOverviewCard");
90
+ const server = useOptionalServer();
91
+ const getMcpTools = server?.getMcpTools;
92
+ const mounts = useMemo(() => editableMountsFromSpec(mcpServers), [mcpServers]);
93
+ const [toolsByServer, setToolsByServer] = useState({});
94
+ const [expandedIds, setExpandedIds] = useState(() => /* @__PURE__ */ new Set());
95
+ useEffect(() => {
96
+ if (getMcpTools === void 0) return;
97
+ let cancelled = false;
98
+ for (const mount of mounts) {
99
+ void getMcpTools({ connectorId: mount.name }).then(
100
+ (tools) => {
101
+ if (!cancelled) setToolsByServer((prev) => ({ ...prev, [mount.name]: tools }));
102
+ },
103
+ () => {
104
+ }
105
+ );
106
+ }
107
+ return () => {
108
+ cancelled = true;
109
+ };
110
+ }, [getMcpTools, mounts]);
111
+ if (mounts.length === 0) {
112
+ return /* @__PURE__ */ jsx(AgentOverviewCard, { title: "MCP Servers & Tools", icon: "plug", count: 0, children: /* @__PURE__ */ jsx("p", { className: "text-text-secondary text-xs", children: "No connectors attached." }) });
113
+ }
114
+ return /* @__PURE__ */ jsx(AgentOverviewCard, { title: "MCP Servers & Tools", icon: "plug", count: mounts.length, children: /* @__PURE__ */ jsx("ul", { className: "space-y-1.5", children: mounts.map((mount) => {
115
+ const tools = toolsByServer[mount.name] ?? [];
116
+ const selectors = approvalSelectorsFromMount(mount.value);
117
+ const enableSelectors = enableSelectorsFromMount(mount.value);
118
+ const enabled = selectedToolNames({
119
+ enableSelectors,
120
+ disableSelectors: disableSelectorsFromMount(mount.value),
121
+ tools
122
+ });
123
+ const toolNames = enabled.names.map((toolName) => {
124
+ const tool = tools.find((item) => item.name === toolName);
125
+ const kind = tool === void 0 ? void 0 : mcpToolKind(tool);
126
+ return {
127
+ toolName,
128
+ kind,
129
+ approvalRequired: namedToolRequiresApproval({ toolName, tools, selectors })
130
+ };
131
+ }).sort((left, right) => KIND_ORDER[left.kind ?? "unknown"] - KIND_ORDER[right.kind ?? "unknown"]);
132
+ const approvalCount = toolNames.filter((tool) => tool.approvalRequired).length;
133
+ const expanded = expandedIds.has(mount.id);
134
+ return /* @__PURE__ */ jsxs("li", { className: "overflow-hidden rounded-md border border-border", children: [
135
+ /* @__PURE__ */ jsxs(
136
+ "button",
137
+ {
138
+ type: "button",
139
+ "aria-expanded": expanded,
140
+ disabled: toolNames.length === 0,
141
+ className: "flex w-full cursor-pointer items-center gap-2 bg-secondary-bg px-2.5 py-2 text-left text-xs hover:bg-ghost-button-hover disabled:cursor-default disabled:hover:bg-secondary-bg",
142
+ onClick: () => setExpandedIds((prev) => {
143
+ const next = new Set(prev);
144
+ if (expanded) next.delete(mount.id);
145
+ else next.add(mount.id);
146
+ return next;
147
+ }),
148
+ children: [
149
+ /* @__PURE__ */ jsx(
150
+ Icon,
151
+ {
152
+ name: "chevron-down",
153
+ className: cn(
154
+ "size-3 shrink-0 text-text-secondary transition-transform",
155
+ expanded ? void 0 : "-rotate-90",
156
+ toolNames.length === 0 && "invisible"
157
+ )
158
+ }
159
+ ),
160
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: mount.name }),
161
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-text-secondary", children: enabled.resolved ? toolCountLabel(toolNames.length) : toolSelectorLabel(enableSelectors) }),
162
+ approvalCount > 0 ? /* @__PURE__ */ jsx(ApprovalCountBadge, { count: approvalCount }) : null
163
+ ]
164
+ }
165
+ ),
166
+ expanded ? /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border border-t border-border", children: toolNames.map(({ toolName, kind, approvalRequired }) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 px-2.5 py-1.5", children: [
167
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-[0.6875rem]", title: toolName, children: toolName }),
168
+ kind ? /* @__PURE__ */ jsx(ToolKindPill, { kind }) : null,
169
+ /* @__PURE__ */ jsx(ApprovalIndicator, { approvalRequired, toolName })
170
+ ] }, toolName)) }) : null
171
+ ] }, mount.id);
172
+ }) }) });
173
+ }
174
+
175
+ // src/atoms/agent-details/AgentOverview.tsx
176
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
177
+ var valueClassName = "text-right font-mono text-primary-button-bg";
178
+ function isRecord(value) {
179
+ return typeof value === "object" && value != null;
180
+ }
181
+ function readName(value) {
182
+ if (!("name" in value) || typeof value.name !== "string") return null;
183
+ return value.name;
184
+ }
185
+ function readRecordValue(record, ...keys) {
186
+ for (const key of keys) {
187
+ const value = record?.[key];
188
+ if (value !== void 0) return value;
189
+ }
190
+ return void 0;
191
+ }
192
+ function displayModelName(name) {
193
+ const slash = name.lastIndexOf("/");
194
+ return slash >= 0 ? name.slice(slash + 1) : name;
195
+ }
196
+ function AgentOverview({ detail }) {
197
+ const Markdown = useSlot("Markdown");
198
+ const AgentOverviewCard = useSlot("AgentOverviewCard");
199
+ const [instructionsView, setInstructionsView] = useState2("markdown");
200
+ const [copied, setCopied] = useState2(false);
201
+ const spec = detail.agentSpec;
202
+ const skills = spec.skills ?? [];
203
+ const modelParams = isRecord(spec.model.params) ? spec.model.params : null;
204
+ const maxTokens = readRecordValue(modelParams, "maxTokens", "max_tokens");
205
+ const temperature = readRecordValue(modelParams, "temperature");
206
+ const config = isRecord(spec.config) ? spec.config : null;
207
+ const sandbox = isRecord(config?.sandbox) ? config.sandbox : null;
208
+ const instructions = spec.instructions?.trim() ? spec.instructions : null;
209
+ const description = detail.description?.trim() ? detail.description : null;
210
+ const execution = [
211
+ ["Sandbox", typeof sandbox?.enabled === "boolean" ? sandbox.enabled ? "Enabled" : "Disabled" : void 0],
212
+ ["Iteration limit", readRecordValue(config, "iterationLimit", "iteration_limit")],
213
+ ["Response format", readRecordValue(config, "responseFormat", "response_format")]
214
+ ].filter((entry) => {
215
+ return typeof entry[1] === "string" || typeof entry[1] === "number";
216
+ });
217
+ const capabilities = [
218
+ ["Generative UI", spec.config?.generativeUi?.enabled],
219
+ ["Dynamic sub-agents", spec.config?.dynamicSubAgents?.enabled],
220
+ ["Ask user questions", spec.config?.askUserQuestions?.enabled]
221
+ ].filter((entry) => typeof entry[1] === "boolean");
222
+ const toggleLabel = instructionsView === "markdown" ? "Raw" : "Markdown";
223
+ return /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-4 md:overflow-hidden", children: /* @__PURE__ */ jsxs2("div", { className: "grid min-h-0 flex-1 gap-3 md:grid-cols-[minmax(0,1fr)_22rem] md:overflow-hidden", children: [
224
+ /* @__PURE__ */ jsxs2("section", { className: "flex min-h-64 flex-col rounded-lg border border-border bg-card-bg p-4 text-text-primary", children: [
225
+ /* @__PURE__ */ jsxs2("div", { className: "mb-3 flex shrink-0 items-center justify-between gap-2", children: [
226
+ /* @__PURE__ */ jsxs2("h2", { className: "flex items-center gap-1.5 text-sm font-semibold text-text-primary", children: [
227
+ /* @__PURE__ */ jsx2(Icon, { name: "book-open", className: "size-4 text-text-secondary" }),
228
+ "Instructions"
229
+ ] }),
230
+ instructions ? /* @__PURE__ */ jsxs2(
231
+ "div",
232
+ {
233
+ className: "inline-flex h-7 items-stretch overflow-hidden rounded-md border border-border bg-primary-bg text-xs font-medium text-text-secondary",
234
+ role: "group",
235
+ "aria-label": "Instructions actions",
236
+ children: [
237
+ /* @__PURE__ */ jsx2(
238
+ "button",
239
+ {
240
+ type: "button",
241
+ "aria-label": `Show ${toggleLabel}`,
242
+ onClick: () => setInstructionsView((view) => view === "markdown" ? "raw" : "markdown"),
243
+ className: "cursor-pointer px-2.5 transition-colors hover:bg-ghost-button-hover hover:text-text-primary",
244
+ children: toggleLabel
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsx2("span", { className: "w-px self-stretch bg-border", "aria-hidden": true }),
248
+ /* @__PURE__ */ jsx2(
249
+ "button",
250
+ {
251
+ type: "button",
252
+ title: copied ? "Copied!" : "Copy",
253
+ "aria-label": copied ? "Copied!" : "Copy",
254
+ onClick: () => {
255
+ void navigator.clipboard.writeText(instructions).then(() => {
256
+ setCopied(true);
257
+ setTimeout(() => setCopied(false), 2e3);
258
+ });
259
+ },
260
+ className: "inline-flex cursor-pointer items-center justify-center px-2 transition-colors hover:bg-ghost-button-hover hover:text-text-primary",
261
+ children: /* @__PURE__ */ jsx2(Icon, { name: copied ? "check" : "copy", size: 12 })
262
+ }
263
+ )
264
+ ]
265
+ }
266
+ ) : null
267
+ ] }),
268
+ /* @__PURE__ */ jsx2("div", { className: "min-h-0 flex-1 overflow-auto", children: instructions ? instructionsView === "markdown" ? /* @__PURE__ */ jsx2(Markdown, { content: instructions, readOnly: true, className: "text-sm" }) : /* @__PURE__ */ jsx2("pre", { className: "whitespace-pre-wrap break-words font-mono text-sm text-text-primary", children: instructions }) : /* @__PURE__ */ jsx2("p", { className: "text-sm text-text-secondary", children: "No instructions for this agent." }) })
269
+ ] }),
270
+ /* @__PURE__ */ jsxs2("aside", { className: "flex min-h-0 min-w-0 flex-col gap-3 md:overflow-auto", children: [
271
+ description ? /* @__PURE__ */ jsx2(AgentOverviewCard, { title: "Description", icon: "file", children: /* @__PURE__ */ jsx2("p", { className: "text-xs text-text-secondary", children: description }) }) : null,
272
+ /* @__PURE__ */ jsx2(AgentOverviewCard, { title: "Model Configuration", icon: "cpu", children: /* @__PURE__ */ jsxs2("dl", { className: "grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs", children: [
273
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: "Model" }),
274
+ /* @__PURE__ */ jsx2("dd", { className: cn(valueClassName, "truncate"), title: spec.model.name, children: displayModelName(spec.model.name) }),
275
+ typeof maxTokens === "number" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
276
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: "Max tokens" }),
277
+ /* @__PURE__ */ jsx2("dd", { className: valueClassName, children: maxTokens })
278
+ ] }) : null,
279
+ spec.model.params?.reasoningEffort !== void 0 ? /* @__PURE__ */ jsxs2(Fragment, { children: [
280
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: "Reasoning" }),
281
+ /* @__PURE__ */ jsx2("dd", { className: valueClassName, children: spec.model.params.reasoningEffort })
282
+ ] }) : null,
283
+ typeof temperature === "number" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
284
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: "Temperature" }),
285
+ /* @__PURE__ */ jsx2("dd", { className: valueClassName, children: temperature })
286
+ ] }) : null
287
+ ] }) }),
288
+ /* @__PURE__ */ jsx2(AgentOverviewMcpServers, { mcpServers: spec.mcpServers }),
289
+ /* @__PURE__ */ jsx2(AgentOverviewCard, { title: "Attached Skills", icon: "lightbulb", count: skills.length, children: skills.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-xs text-text-secondary", children: "No skills attached." }) : /* @__PURE__ */ jsx2("ul", { className: "space-y-1.5", children: skills.map((skill, index) => /* @__PURE__ */ jsx2(
290
+ "li",
291
+ {
292
+ className: "rounded-md bg-secondary-bg px-2 py-1.5 text-xs",
293
+ children: readName(skill) ?? `Skill ${index + 1}`
294
+ },
295
+ `${readName(skill) ?? "skill"}-${index}`
296
+ )) }) }),
297
+ execution.length > 0 ? /* @__PURE__ */ jsx2(AgentOverviewCard, { title: "Execution", icon: "terminal", children: /* @__PURE__ */ jsx2("dl", { className: "space-y-1 text-xs", children: execution.map(([label, value]) => /* @__PURE__ */ jsxs2("div", { className: "flex justify-between gap-3", children: [
298
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: label }),
299
+ /* @__PURE__ */ jsx2("dd", { className: valueClassName, children: value })
300
+ ] }, label)) }) }) : null,
301
+ capabilities.length > 0 ? /* @__PURE__ */ jsx2(AgentOverviewCard, { title: "Capabilities", icon: "cube", children: /* @__PURE__ */ jsx2("dl", { className: "space-y-1 text-xs", children: capabilities.map(([label, enabled]) => /* @__PURE__ */ jsxs2("div", { className: "flex justify-between gap-3", children: [
302
+ /* @__PURE__ */ jsx2("dt", { className: "text-text-secondary", children: label }),
303
+ /* @__PURE__ */ jsx2("dd", { className: valueClassName, children: enabled ? "Enabled" : "Disabled" })
304
+ ] }, label)) }) }) : null
305
+ ] })
306
+ ] }) });
307
+ }
308
+ export {
309
+ AgentOverview as default
310
+ };
311
+ //# sourceMappingURL=AgentOverview-3LJZ6MO7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentOverview.tsx","../src/atoms/agent-details/AgentOverviewMcpServers.tsx"],"sourcesContent":["'use client';\n\nimport { useState, type ComponentType } from 'react';\nimport { Icon } from '../../icons/Icon.js';\nimport { useSlot } from '../../theme/SlotsProvider.js';\nimport { cn } from '../lib/cn.js';\nimport { AgentOverviewMcpServers } from './AgentOverviewMcpServers.js';\nimport type { AgentOverviewProps } from './types.js';\n\ntype InstructionsView = 'markdown' | 'raw';\n\nconst valueClassName = 'text-right font-mono text-primary-button-bg';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value != null;\n}\n\nfunction readName(value: object): string | null {\n if (!('name' in value) || typeof value.name !== 'string') return null;\n return value.name;\n}\n\nfunction readRecordValue(record: Record<string, unknown> | null, ...keys: string[]): unknown {\n for (const key of keys) {\n const value = record?.[key];\n if (value !== undefined) return value;\n }\n return undefined;\n}\n\nfunction displayModelName(name: string): string {\n const slash = name.lastIndexOf('/');\n return slash >= 0 ? name.slice(slash + 1) : name;\n}\n\nexport default function AgentOverview({ detail }: AgentOverviewProps) {\n const Markdown = useSlot('Markdown');\n const AgentOverviewCard = useSlot('AgentOverviewCard');\n const [instructionsView, setInstructionsView] = useState<InstructionsView>('markdown');\n const [copied, setCopied] = useState(false);\n const spec = detail.agentSpec;\n const skills = spec.skills ?? [];\n const modelParams = isRecord(spec.model.params) ? spec.model.params : null;\n const maxTokens = readRecordValue(modelParams, 'maxTokens', 'max_tokens');\n const temperature = readRecordValue(modelParams, 'temperature');\n const config = isRecord(spec.config) ? spec.config : null;\n const sandbox = isRecord(config?.sandbox) ? config.sandbox : null;\n const instructions = spec.instructions?.trim() ? spec.instructions : null;\n const description = detail.description?.trim() ? detail.description : null;\n const execution = [\n ['Sandbox', typeof sandbox?.enabled === 'boolean' ? (sandbox.enabled ? 'Enabled' : 'Disabled') : undefined],\n ['Iteration limit', readRecordValue(config, 'iterationLimit', 'iteration_limit')],\n ['Response format', readRecordValue(config, 'responseFormat', 'response_format')],\n ].filter((entry): entry is [string, string | number] => {\n return typeof entry[1] === 'string' || typeof entry[1] === 'number';\n });\n const capabilities = [\n ['Generative UI', spec.config?.generativeUi?.enabled],\n ['Dynamic sub-agents', spec.config?.dynamicSubAgents?.enabled],\n ['Ask user questions', spec.config?.askUserQuestions?.enabled],\n ].filter((entry): entry is [string, boolean] => typeof entry[1] === 'boolean');\n const toggleLabel = instructionsView === 'markdown' ? 'Raw' : 'Markdown';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-4 md:overflow-hidden\">\n <div className=\"grid min-h-0 flex-1 gap-3 md:grid-cols-[minmax(0,1fr)_22rem] md:overflow-hidden\">\n <section className=\"flex min-h-64 flex-col rounded-lg border border-border bg-card-bg p-4 text-text-primary\">\n <div className=\"mb-3 flex shrink-0 items-center justify-between gap-2\">\n <h2 className=\"flex items-center gap-1.5 text-sm font-semibold text-text-primary\">\n <Icon name=\"book-open\" className=\"size-4 text-text-secondary\" />\n Instructions\n </h2>\n {instructions ? (\n <div\n className=\"inline-flex h-7 items-stretch overflow-hidden rounded-md border border-border bg-primary-bg text-xs font-medium text-text-secondary\"\n role=\"group\"\n aria-label=\"Instructions actions\"\n >\n <button\n type=\"button\"\n aria-label={`Show ${toggleLabel}`}\n onClick={() => setInstructionsView(view => (view === 'markdown' ? 'raw' : 'markdown'))}\n className=\"cursor-pointer px-2.5 transition-colors hover:bg-ghost-button-hover hover:text-text-primary\"\n >\n {toggleLabel}\n </button>\n <span className=\"w-px self-stretch bg-border\" aria-hidden />\n <button\n type=\"button\"\n title={copied ? 'Copied!' : 'Copy'}\n aria-label={copied ? 'Copied!' : 'Copy'}\n onClick={() => {\n void navigator.clipboard.writeText(instructions).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }}\n className=\"inline-flex cursor-pointer items-center justify-center px-2 transition-colors hover:bg-ghost-button-hover hover:text-text-primary\"\n >\n <Icon name={copied ? 'check' : 'copy'} size={12} />\n </button>\n </div>\n ) : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {instructions ? (\n instructionsView === 'markdown' ? (\n <Markdown content={instructions} readOnly className=\"text-sm\" />\n ) : (\n <pre className=\"whitespace-pre-wrap break-words font-mono text-sm text-text-primary\">\n {instructions}\n </pre>\n )\n ) : (\n <p className=\"text-sm text-text-secondary\">No instructions for this agent.</p>\n )}\n </div>\n </section>\n\n <aside className=\"flex min-h-0 min-w-0 flex-col gap-3 md:overflow-auto\">\n {description ? (\n <AgentOverviewCard title=\"Description\" icon=\"file\">\n <p className=\"text-xs text-text-secondary\">{description}</p>\n </AgentOverviewCard>\n ) : null}\n <AgentOverviewCard title=\"Model Configuration\" icon=\"cpu\">\n <dl className=\"grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs\">\n <dt className=\"text-text-secondary\">Model</dt>\n <dd className={cn(valueClassName, 'truncate')} title={spec.model.name}>\n {displayModelName(spec.model.name)}\n </dd>\n {typeof maxTokens === 'number' ? (\n <>\n <dt className=\"text-text-secondary\">Max tokens</dt>\n <dd className={valueClassName}>{maxTokens}</dd>\n </>\n ) : null}\n {spec.model.params?.reasoningEffort !== undefined ? (\n <>\n <dt className=\"text-text-secondary\">Reasoning</dt>\n <dd className={valueClassName}>{spec.model.params.reasoningEffort}</dd>\n </>\n ) : null}\n {typeof temperature === 'number' ? (\n <>\n <dt className=\"text-text-secondary\">Temperature</dt>\n <dd className={valueClassName}>{temperature}</dd>\n </>\n ) : null}\n </dl>\n </AgentOverviewCard>\n <AgentOverviewMcpServers mcpServers={spec.mcpServers} />\n\n <AgentOverviewCard title=\"Attached Skills\" icon=\"lightbulb\" count={skills.length}>\n {skills.length === 0 ? (\n <p className=\"text-xs text-text-secondary\">No skills attached.</p>\n ) : (\n <ul className=\"space-y-1.5\">\n {skills.map((skill, index) => (\n <li\n key={`${readName(skill) ?? 'skill'}-${index}`}\n className=\"rounded-md bg-secondary-bg px-2 py-1.5 text-xs\"\n >\n {readName(skill) ?? `Skill ${index + 1}`}\n </li>\n ))}\n </ul>\n )}\n </AgentOverviewCard>\n\n {execution.length > 0 ? (\n <AgentOverviewCard title=\"Execution\" icon=\"terminal\">\n <dl className=\"space-y-1 text-xs\">\n {execution.map(([label, value]) => (\n <div key={label} className=\"flex justify-between gap-3\">\n <dt className=\"text-text-secondary\">{label}</dt>\n <dd className={valueClassName}>{value}</dd>\n </div>\n ))}\n </dl>\n </AgentOverviewCard>\n ) : null}\n\n {capabilities.length > 0 ? (\n <AgentOverviewCard title=\"Capabilities\" icon=\"cube\">\n <dl className=\"space-y-1 text-xs\">\n {capabilities.map(([label, enabled]) => (\n <div key={label} className=\"flex justify-between gap-3\">\n <dt className=\"text-text-secondary\">{label}</dt>\n <dd className={valueClassName}>{enabled ? 'Enabled' : 'Disabled'}</dd>\n </div>\n ))}\n </dl>\n </AgentOverviewCard>\n ) : null}\n </aside>\n </div>\n </div>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentOverview: ComponentType<AgentOverviewProps>;\n }\n}\n","'use client';\n\nimport { useEffect, useMemo, useState } from 'react';\n\nimport { Icon } from '../../icons/Icon.js';\nimport { useOptionalServer } from '../../server/ServerContext.js';\nimport type { McpToolSelection } from '../../server/types.js';\nimport { useSlot } from '../../theme/SlotsProvider.js';\nimport {\n approvalSelectorsFromMount,\n disableSelectorsFromMount,\n editableMountsFromSpec,\n enableSelectorsFromMount,\n} from '../draft/agentConfigMounts.js';\nimport { namedToolRequiresApproval } from '../draft/mcpToolApprovals.js';\nimport { mcpToolKind, type McpToolKind } from '../draft/mcpToolSections.js';\nimport { selectedToolNames, TOOL_TAG_ALL } from '../draft/mcpToolSelectors.js';\nimport { cn } from '../lib/cn.js';\nimport { Tooltip } from '../primitives/Tooltip.js';\n\nconst KIND_CLASSES: Record<McpToolKind, string> = {\n read: 'border-border bg-secondary-bg text-text-secondary',\n write: 'border-border bg-secondary-bg text-text-primary',\n destructive: 'border-failure-bg/30 bg-failure-bg/10 text-failure-bg',\n};\n\n/** Read-only tools first and destructive last, mirroring the tool picker's sections. */\nconst KIND_ORDER: Record<McpToolKind | 'unknown', number> = {\n read: 0,\n write: 1,\n unknown: 2,\n destructive: 3,\n};\n\nfunction toolCountLabel(count: number): string {\n return count === 1 ? '1 tool' : `${count} tools`;\n}\n\n/** Shown while tags cannot be resolved: the selectors themselves are the best available answer. */\nfunction toolSelectorLabel(enableSelectors: readonly string[]): string {\n if (enableSelectors.includes(TOOL_TAG_ALL)) return 'All tools';\n return enableSelectors.filter(selector => selector.startsWith('@')).join(' ');\n}\n\nfunction ApprovalCountBadge({ count }: { count: number }) {\n return (\n <span\n className=\"border-warning-bg/40 bg-warning-bg/10 text-warning-bg inline-flex shrink-0 items-center gap-1 rounded-full border px-1.5 py-0.5 text-[0.625rem] font-medium\"\n aria-label={`${count} ${count === 1 ? 'tool needs' : 'tools need'} approval`}\n >\n <Icon name=\"shield-check\" className=\"size-2.5\" />\n {count}\n </span>\n );\n}\n\nfunction ToolKindPill({ kind }: { kind: McpToolKind }) {\n return (\n <span className={cn('shrink-0 rounded-full border px-1.5 py-0.5 text-[0.625rem] font-medium', KIND_CLASSES[kind])}>\n {kind}\n </span>\n );\n}\n\nfunction ApprovalIndicator({ approvalRequired, toolName }: { approvalRequired: boolean; toolName: string }) {\n return (\n <Tooltip\n content={approvalRequired ? 'Asks for approval before running' : 'Runs without asking for approval'}\n triggerClassName=\"shrink-0\"\n >\n <span\n role=\"img\"\n aria-label={`${toolName} ${approvalRequired ? 'requires approval' : 'runs without approval'}`}\n className={cn(\n 'flex size-5 items-center justify-center rounded-md border',\n approvalRequired\n ? 'border-warning-bg/50 bg-warning-bg/10 text-warning-bg'\n : 'border-border text-text-secondary',\n )}\n >\n <Icon name={approvalRequired ? 'shield-check' : 'shield'} className=\"size-3\" />\n </span>\n </Tooltip>\n );\n}\n\n/** Attached MCP servers, each expanding into the tools the agent can call. */\nexport function AgentOverviewMcpServers({ mcpServers }: { mcpServers: unknown }) {\n const AgentOverviewCard = useSlot('AgentOverviewCard');\n const server = useOptionalServer();\n const getMcpTools = server?.getMcpTools;\n const mounts = useMemo(() => editableMountsFromSpec(mcpServers), [mcpServers]);\n const [toolsByServer, setToolsByServer] = useState<Record<string, McpToolSelection[]>>({});\n const [expandedIds, setExpandedIds] = useState<ReadonlySet<string>>(() => new Set());\n\n // Tool metadata drives the counts, kinds, and approval state; a failing server just shows less.\n useEffect(() => {\n if (getMcpTools === undefined) return;\n let cancelled = false;\n for (const mount of mounts) {\n void getMcpTools({ connectorId: mount.name }).then(\n tools => {\n if (!cancelled) setToolsByServer(prev => ({ ...prev, [mount.name]: tools }));\n },\n () => {},\n );\n }\n return () => {\n cancelled = true;\n };\n }, [getMcpTools, mounts]);\n\n if (mounts.length === 0) {\n return (\n <AgentOverviewCard title=\"MCP Servers & Tools\" icon=\"plug\" count={0}>\n <p className=\"text-text-secondary text-xs\">No connectors attached.</p>\n </AgentOverviewCard>\n );\n }\n\n return (\n <AgentOverviewCard title=\"MCP Servers & Tools\" icon=\"plug\" count={mounts.length}>\n <ul className=\"space-y-1.5\">\n {mounts.map(mount => {\n const tools = toolsByServer[mount.name] ?? [];\n const selectors = approvalSelectorsFromMount(mount.value);\n const enableSelectors = enableSelectorsFromMount(mount.value);\n const enabled = selectedToolNames({\n enableSelectors,\n disableSelectors: disableSelectorsFromMount(mount.value),\n tools,\n });\n const toolNames = enabled.names\n .map(toolName => {\n const tool = tools.find(item => item.name === toolName);\n const kind = tool === undefined ? undefined : mcpToolKind(tool);\n return {\n toolName,\n kind,\n approvalRequired: namedToolRequiresApproval({ toolName, tools, selectors }),\n };\n })\n .sort((left, right) => KIND_ORDER[left.kind ?? 'unknown'] - KIND_ORDER[right.kind ?? 'unknown']);\n const approvalCount = toolNames.filter(tool => tool.approvalRequired).length;\n const expanded = expandedIds.has(mount.id);\n return (\n <li key={mount.id} className=\"overflow-hidden rounded-md border border-border\">\n <button\n type=\"button\"\n aria-expanded={expanded}\n disabled={toolNames.length === 0}\n className=\"flex w-full cursor-pointer items-center gap-2 bg-secondary-bg px-2.5 py-2 text-left text-xs hover:bg-ghost-button-hover disabled:cursor-default disabled:hover:bg-secondary-bg\"\n onClick={() =>\n setExpandedIds(prev => {\n const next = new Set(prev);\n if (expanded) next.delete(mount.id);\n else next.add(mount.id);\n return next;\n })\n }\n >\n <Icon\n name=\"chevron-down\"\n className={cn(\n 'size-3 shrink-0 text-text-secondary transition-transform',\n expanded ? undefined : '-rotate-90',\n toolNames.length === 0 && 'invisible',\n )}\n />\n <span className=\"min-w-0 flex-1 truncate font-medium\">{mount.name}</span>\n <span className=\"shrink-0 text-text-secondary\">\n {enabled.resolved ? toolCountLabel(toolNames.length) : toolSelectorLabel(enableSelectors)}\n </span>\n {approvalCount > 0 ? <ApprovalCountBadge count={approvalCount} /> : null}\n </button>\n {expanded ? (\n <ul className=\"divide-y divide-border border-t border-border\">\n {toolNames.map(({ toolName, kind, approvalRequired }) => (\n <li key={toolName} className=\"flex items-center gap-2 px-2.5 py-1.5\">\n <span className=\"min-w-0 flex-1 truncate font-mono text-[0.6875rem]\" title={toolName}>\n {toolName}\n </span>\n {kind ? <ToolKindPill kind={kind} /> : null}\n <ApprovalIndicator approvalRequired={approvalRequired} toolName={toolName} />\n </li>\n ))}\n </ul>\n ) : null}\n </li>\n );\n })}\n </ul>\n </AgentOverviewCard>\n );\n}\n"],"mappings":"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","names":["useState","jsx","jsxs","useState"]}
@@ -1,22 +1,25 @@
1
1
  "use client";
2
2
  import {
3
3
  SESSION_EVENT_TYPES,
4
- useSlot
5
- } from "./chunk-ZTMKFZQ3.js";
6
- import "./chunk-2XPPBEYF.js";
7
- import "./chunk-XAU7QFG3.js";
8
- import "./chunk-U7KURWW3.js";
4
+ getSessionEventColor,
5
+ useSlot,
6
+ useThemeMode
7
+ } from "./chunk-OH357IHR.js";
8
+ import "./chunk-T6QQV5LK.js";
9
+ import "./chunk-5N5V7YLO.js";
10
+ import "./chunk-2GIZY3JJ.js";
9
11
  import "./chunk-M6MHLVSO.js";
10
- import "./chunk-MPNSO7E6.js";
12
+ import "./chunk-SLMFEG7X.js";
11
13
  import {
12
14
  cn
13
- } from "./chunk-7Z2C2K7F.js";
15
+ } from "./chunk-GKXDRULM.js";
14
16
 
15
17
  // src/atoms/agent-details/AgentSessionEventTimeline.tsx
16
18
  import { useCallback, useMemo, useState } from "react";
17
19
  import { jsx, jsxs } from "react/jsx-runtime";
18
20
  function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
19
21
  const AgentSessionEventTimelineChart = useSlot("AgentSessionEventTimelineChart");
22
+ const isDark = useThemeMode() === "dark";
20
23
  const [hiddenTypes, setHiddenTypes] = useState(() => /* @__PURE__ */ new Set());
21
24
  const availableEventTypes = useMemo(() => {
22
25
  const available = new Set(segments.map((segment) => segment.type));
@@ -52,7 +55,13 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
52
55
  ),
53
56
  onClick: () => handleToggleType(eventType.id),
54
57
  children: [
55
- /* @__PURE__ */ jsx("span", { className: "size-2 rounded-sm", style: { backgroundColor: eventType.color } }),
58
+ /* @__PURE__ */ jsx(
59
+ "span",
60
+ {
61
+ className: "size-2 rounded-sm",
62
+ style: { backgroundColor: getSessionEventColor(eventType.id, isDark) }
63
+ }
64
+ ),
56
65
  eventType.label
57
66
  ]
58
67
  },
@@ -62,7 +71,7 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
62
71
  ]
63
72
  }
64
73
  ),
65
- /* @__PURE__ */ jsx("div", { className: "w-full py-2", children: /* @__PURE__ */ jsx(
74
+ /* @__PURE__ */ jsx("div", { className: "w-full p-2", children: /* @__PURE__ */ jsx(
66
75
  AgentSessionEventTimelineChart,
67
76
  {
68
77
  turns,
@@ -76,4 +85,4 @@ function AgentSessionEventTimeline({ turns, segments, onSelectTurn }) {
76
85
  export {
77
86
  AgentSessionEventTimeline
78
87
  };
79
- //# sourceMappingURL=AgentSessionEventTimeline-26Z6IB3B.js.map
88
+ //# sourceMappingURL=AgentSessionEventTimeline-5GOJKT7D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentSessionEventTimeline.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useState, type ComponentType } from 'react';\n\nimport { useSlot, useThemeMode } from '../../theme/SlotsProvider.js';\nimport { getSessionEventColor, SESSION_EVENT_TYPES, type SessionEventType } from '../../utils/sessionEventTimeline.js';\nimport { cn } from '../lib/cn.js';\nimport type { AgentSessionEventTimelineProps } from './types.js';\n\nexport function AgentSessionEventTimeline({ turns, segments, onSelectTurn }: AgentSessionEventTimelineProps) {\n const AgentSessionEventTimelineChart = useSlot('AgentSessionEventTimelineChart');\n const isDark = useThemeMode() === 'dark';\n const [hiddenTypes, setHiddenTypes] = useState<Set<SessionEventType>>(() => new Set());\n\n const availableEventTypes = useMemo(() => {\n const available = new Set(segments.map(segment => segment.type));\n return SESSION_EVENT_TYPES.filter(eventType => available.has(eventType.id));\n }, [segments]);\n\n const handleToggleType = useCallback((type: SessionEventType) => {\n setHiddenTypes(previous => {\n const next = new Set(previous);\n if (next.has(type)) next.delete(type);\n else next.add(type);\n return next;\n });\n }, []);\n\n if (segments.length === 0) return null;\n\n return (\n <div className=\"w-full\" data-slot=\"agent-session-event-timeline\">\n <div\n className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2\"\n data-slot=\"agent-session-event-types\"\n >\n <span className=\"text-xs font-medium uppercase text-text-secondary\">Event types</span>\n <div className=\"flex flex-wrap items-center gap-1\">\n {availableEventTypes.map(eventType => {\n const isVisible = !hiddenTypes.has(eventType.id);\n return (\n <button\n key={eventType.id}\n type=\"button\"\n aria-pressed={isVisible}\n className={cn(\n 'flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium',\n isVisible ? 'border-border text-text-primary' : 'border-transparent text-text-secondary opacity-80',\n )}\n onClick={() => handleToggleType(eventType.id)}\n >\n <span\n className=\"size-2 rounded-sm\"\n style={{ backgroundColor: getSessionEventColor(eventType.id, isDark) }}\n />\n {eventType.label}\n </button>\n );\n })}\n </div>\n </div>\n <div className=\"w-full p-2\">\n <AgentSessionEventTimelineChart\n turns={turns}\n segments={segments}\n hiddenTypes={hiddenTypes}\n onSelectTurn={onSelectTurn}\n />\n </div>\n </div>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentSessionEventTimeline: ComponentType<AgentSessionEventTimelineProps>;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAEA,SAAS,aAAa,SAAS,gBAAoC;AAkC3D,cAKM,YALN;AA3BD,SAAS,0BAA0B,EAAE,OAAO,UAAU,aAAa,GAAmC;AAC3G,QAAM,iCAAiC,QAAQ,gCAAgC;AAC/E,QAAM,SAAS,aAAa,MAAM;AAClC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAgC,MAAM,oBAAI,IAAI,CAAC;AAErF,QAAM,sBAAsB,QAAQ,MAAM;AACxC,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,aAAW,QAAQ,IAAI,CAAC;AAC/D,WAAO,oBAAoB,OAAO,eAAa,UAAU,IAAI,UAAU,EAAE,CAAC;AAAA,EAC5E,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,mBAAmB,YAAY,CAAC,SAA2B;AAC/D,mBAAe,cAAY;AACzB,YAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,UAAI,KAAK,IAAI,IAAI,EAAG,MAAK,OAAO,IAAI;AAAA,UAC/B,MAAK,IAAI,IAAI;AAClB,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,SACE,qBAAC,SAAI,WAAU,UAAS,aAAU,gCAChC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAU;AAAA,QAEV;AAAA,8BAAC,UAAK,WAAU,qDAAoD,yBAAW;AAAA,UAC/E,oBAAC,SAAI,WAAU,qCACZ,8BAAoB,IAAI,eAAa;AACpC,kBAAM,YAAY,CAAC,YAAY,IAAI,UAAU,EAAE;AAC/C,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,gBAAc;AAAA,gBACd,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY,oCAAoC;AAAA,gBAClD;AAAA,gBACA,SAAS,MAAM,iBAAiB,UAAU,EAAE;AAAA,gBAE5C;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,OAAO,EAAE,iBAAiB,qBAAqB,UAAU,IAAI,MAAM,EAAE;AAAA;AAAA,kBACvE;AAAA,kBACC,UAAU;AAAA;AAAA;AAAA,cAbN,UAAU;AAAA,YAcjB;AAAA,UAEJ,CAAC,GACH;AAAA;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,SAAI,WAAU,cACb;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;","names":[]}