@tangle-network/ui 11.10.0 → 11.11.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 (130) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/active-sessions-store-Gt1R0rFG.js +262 -0
  3. package/dist/{active-sessions-store-CeOmXgv5.d.ts → active-sessions-store-nl70ZnMC.d.ts} +40 -41
  4. package/dist/artifact-pane-BL_DFWNl.d.ts +32 -0
  5. package/dist/artifact-pane-DMXT9a8U.js +70 -0
  6. package/dist/auth-DixfCMCk.js +154 -0
  7. package/dist/auth.d.ts +2 -74
  8. package/dist/auth.js +2 -16
  9. package/dist/branding-26d5ARIr.d.ts +14 -0
  10. package/dist/button-uhNnwdsD.js +78 -0
  11. package/dist/button-yoIv77e2.d.ts +16 -0
  12. package/dist/chat-CPLL0Fd9.js +667 -0
  13. package/dist/chat.d.ts +2 -201
  14. package/dist/chat.js +2 -31
  15. package/dist/code-block-B9miUPht.d.ts +23 -0
  16. package/dist/code-block-CngSn37j.js +165 -0
  17. package/dist/diff-preview-cySuqowW.js +533 -0
  18. package/dist/document-editor-pane-BcoABlhn.d.ts +131 -0
  19. package/dist/document-editor-pane-Cz6oEF1o.js +1287 -0
  20. package/dist/dropdown-menu-BpcLa5vF.js +101 -0
  21. package/dist/editor.d.ts +76 -78
  22. package/dist/editor.js +2 -34
  23. package/dist/file-format-BgXbr-Ib.js +160 -0
  24. package/dist/files-CYlOo0mE.js +743 -0
  25. package/dist/files.d.ts +2 -243
  26. package/dist/files.js +3 -41
  27. package/dist/focus-Cw02pNSr.js +56 -0
  28. package/dist/format-DfcLWqMa.js +54 -0
  29. package/dist/hooks.d.ts +30 -37
  30. package/dist/hooks.js +111 -46
  31. package/dist/index-2UntyjBb.d.ts +52 -0
  32. package/dist/index-COgqsFAQ.d.ts +42 -0
  33. package/dist/index-CPDET_s1.d.ts +549 -0
  34. package/dist/index-CUhfHT_V.d.ts +204 -0
  35. package/dist/index-Cg6gYAqh.d.ts +73 -0
  36. package/dist/index-Cq-EJzqW.d.ts +16 -0
  37. package/dist/index-DhYmSaLF.d.ts +245 -0
  38. package/dist/index-DjKxO357.d.ts +128 -0
  39. package/dist/index-b56ew9aF.d.ts +107 -0
  40. package/dist/index.d.ts +26 -43
  41. package/dist/index.js +35 -472
  42. package/dist/markdown-BprL96Gl.js +45 -0
  43. package/dist/markdown.d.ts +3 -18
  44. package/dist/markdown.js +3 -15
  45. package/dist/message-vhUI0c5G.d.ts +16 -0
  46. package/dist/nav.d.ts +6 -8
  47. package/dist/nav.js +29 -11
  48. package/dist/openui-artifact-renderer-D3E5bIAI.d.ts +114 -0
  49. package/dist/openui-artifact-renderer-DT4xbvWt.js +266 -0
  50. package/dist/openui.d.ts +2 -115
  51. package/dist/openui.js +2 -13
  52. package/dist/parts-5mhy9yJ3.d.ts +37 -0
  53. package/dist/primitives-DE-blUz-.js +1239 -0
  54. package/dist/primitives.d.ts +5 -525
  55. package/dist/primitives.js +9 -212
  56. package/dist/redaction-CGGB2ENG.js +74 -0
  57. package/dist/redaction.d.ts +2 -42
  58. package/dist/redaction.js +2 -7
  59. package/dist/run-OyWmIDqu.d.ts +41 -0
  60. package/dist/run-ZsIKPA6J.js +17 -0
  61. package/dist/run-group-D1InSdQu.js +410 -0
  62. package/dist/run.d.ts +3 -126
  63. package/dist/run.js +5 -40
  64. package/dist/sdk-hooks.d.ts +2 -285
  65. package/dist/sdk-hooks.js +3 -36
  66. package/dist/stores.d.ts +13 -14
  67. package/dist/stores.js +34 -76
  68. package/dist/table-DHyqDPbU.js +146 -0
  69. package/dist/tabs-ujuqAdtb.js +40 -0
  70. package/dist/text-shimmer-BUUo6I-g.js +64 -0
  71. package/dist/tool-call-feed-BeB1_4pX.d.ts +47 -0
  72. package/dist/tool-call-feed-C1W1N54c.js +109 -0
  73. package/dist/tool-call-step-Bi3_YJRV.js +434 -0
  74. package/dist/tool-display-BAuAVa43.js +158 -0
  75. package/dist/{tool-display-z4JcDmMQ.d.ts → tool-display-DgmL5rIU.d.ts} +16 -16
  76. package/dist/tool-previews.d.ts +2 -48
  77. package/dist/tool-previews.js +2 -23
  78. package/dist/types.d.ts +6 -19
  79. package/dist/types.js +0 -1
  80. package/dist/use-auto-scroll-C5Pjeqon.js +153 -0
  81. package/dist/use-sse-stream-BjVBDbxK.js +884 -0
  82. package/dist/use-sse-stream-Dm6R5YWz.d.ts +282 -0
  83. package/dist/utils-Bl_CZ0Qp.js +37 -0
  84. package/dist/{chunk-RQHJBTEU.js → utils-C_uf36nf.js} +4 -6
  85. package/dist/utils.d.ts +2 -104
  86. package/dist/utils.js +6 -44
  87. package/package.json +39 -41
  88. package/dist/artifact-pane-DpuWcAiF.d.ts +0 -33
  89. package/dist/button-CMQuQEW_.d.ts +0 -17
  90. package/dist/chunk-34A66VBG.js +0 -214
  91. package/dist/chunk-3OI2QKFD.js +0 -0
  92. package/dist/chunk-3XXBZL53.js +0 -174
  93. package/dist/chunk-42PAH5D2.js +0 -112
  94. package/dist/chunk-4CLN43XT.js +0 -45
  95. package/dist/chunk-55WHV7SS.js +0 -1604
  96. package/dist/chunk-565EATZZ.js +0 -156
  97. package/dist/chunk-5Z5ZYMOJ.js +0 -0
  98. package/dist/chunk-6BGQA4BQ.js +0 -0
  99. package/dist/chunk-BEBXZPHW.js +0 -299
  100. package/dist/chunk-C5WF4WMV.js +0 -734
  101. package/dist/chunk-HFL6R6IF.js +0 -37
  102. package/dist/chunk-HGML45QH.js +0 -104
  103. package/dist/chunk-HMAPIH7L.js +0 -595
  104. package/dist/chunk-K5XFRUS4.js +0 -1401
  105. package/dist/chunk-KFQGHD73.js +0 -198
  106. package/dist/chunk-L57WRIND.js +0 -59
  107. package/dist/chunk-LTEKI7YJ.js +0 -59
  108. package/dist/chunk-M3QZK62R.js +0 -233
  109. package/dist/chunk-ND3ZFXQK.js +0 -179
  110. package/dist/chunk-OEX7NZE3.js +0 -321
  111. package/dist/chunk-OL5GYLHV.js +0 -60
  112. package/dist/chunk-QGFYBNSO.js +0 -133
  113. package/dist/chunk-R7B3UWPF.js +0 -550
  114. package/dist/chunk-R7SUY4E3.js +0 -65
  115. package/dist/chunk-REJESC5U.js +0 -117
  116. package/dist/chunk-RQGKSCEZ.js +0 -0
  117. package/dist/chunk-SNLR2AEA.js +0 -40
  118. package/dist/chunk-WKWBTL2V.js +0 -15
  119. package/dist/chunk-X7CU776B.js +0 -1048
  120. package/dist/chunk-XU3HB5QL.js +0 -127
  121. package/dist/chunk-YTO5V6QS.js +0 -19
  122. package/dist/chunk-YU4E5J2N.js +0 -437
  123. package/dist/chunk-YZ6AK25N.js +0 -886
  124. package/dist/code-block-0kSpWMnf.d.ts +0 -25
  125. package/dist/document-editor-pane-IAEQn_Dl.d.ts +0 -128
  126. package/dist/document-editor-pane-QHDOBA43.js +0 -13
  127. package/dist/message-BHWbxBtT.d.ts +0 -15
  128. package/dist/parts-dj7AcUg0.d.ts +0 -36
  129. package/dist/run-PfLmDAox.d.ts +0 -41
  130. package/dist/tool-call-feed-D9iofJgW.d.ts +0 -46
@@ -1,127 +0,0 @@
1
- // src/files/file-format.ts
2
- var IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "svg", "webp", "avif"];
3
- var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
4
- var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a"];
5
- var SPREADSHEET_MIME_TYPES = [
6
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
7
- "application/vnd.ms-excel"
8
- ];
9
- var EXTENSION_TO_SYNTAX_LANGUAGE = {
10
- ts: "typescript",
11
- tsx: "tsx",
12
- js: "javascript",
13
- jsx: "jsx",
14
- mjs: "javascript",
15
- cjs: "javascript",
16
- rs: "rust",
17
- py: "python",
18
- go: "go",
19
- rb: "ruby",
20
- json: "json",
21
- yaml: "yaml",
22
- yml: "yaml",
23
- toml: "toml",
24
- md: "markdown",
25
- markdown: "markdown",
26
- css: "css",
27
- scss: "scss",
28
- html: "html",
29
- sh: "bash",
30
- bash: "bash",
31
- zsh: "bash",
32
- bashrc: "bash",
33
- bash_logout: "bash",
34
- profile: "bash",
35
- sql: "sql",
36
- sol: "solidity",
37
- proto: "protobuf"
38
- };
39
- var NON_CODE_SYNTAX_EXTENSIONS = /* @__PURE__ */ new Set(["json", "yaml", "yml", "md", "markdown"]);
40
- var PLAIN_CODE_EXTENSIONS = ["env", "gitignore"];
41
- var CODE_EXTENSIONS = /* @__PURE__ */ new Set([
42
- ...Object.keys(EXTENSION_TO_SYNTAX_LANGUAGE).filter((ext) => !NON_CODE_SYNTAX_EXTENSIONS.has(ext)),
43
- ...PLAIN_CODE_EXTENSIONS
44
- ]);
45
- function fileExtension(filename) {
46
- const base = filename.slice(filename.lastIndexOf("/") + 1);
47
- const dot = base.lastIndexOf(".");
48
- if (dot < 0) return "";
49
- return base.slice(dot + 1).toLowerCase();
50
- }
51
- function mimeEssence(mimeType) {
52
- return mimeType?.split(";")[0]?.trim().toLowerCase() ?? "";
53
- }
54
- function detectFileFormat(filename, mimeType) {
55
- const ext = fileExtension(filename);
56
- const mime = mimeEssence(mimeType);
57
- if (mime === "application/pdf") return "pdf";
58
- if (mime.startsWith("image/")) return "image";
59
- if (mime.startsWith("video/")) return "video";
60
- if (mime.startsWith("audio/")) return "audio";
61
- if (mime === "text/markdown") return "markdown";
62
- if (mime === "application/json") return "json";
63
- if (mime === "text/csv" || mime === "application/csv") return "csv";
64
- if (SPREADSHEET_MIME_TYPES.includes(mime)) return "spreadsheet";
65
- if (mime === "application/yaml" || mime === "application/x-yaml" || mime === "text/yaml") return "yaml";
66
- if (ext === "pdf") return "pdf";
67
- if (IMAGE_EXTENSIONS.includes(ext)) return "image";
68
- if (VIDEO_EXTENSIONS.includes(ext)) return "video";
69
- if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
70
- if (ext === "csv") return "csv";
71
- if (ext === "xlsx" || ext === "xls") return "spreadsheet";
72
- if (CODE_EXTENSIONS.has(ext)) return "code";
73
- if (ext === "json") return "json";
74
- if (ext === "yaml" || ext === "yml") return "yaml";
75
- if (ext === "md" || ext === "markdown") return "markdown";
76
- if (["txt", "log", "text"].includes(ext)) return "text";
77
- if (mime === "text/plain") return "text";
78
- return "unknown";
79
- }
80
- function resolveFilePreviewKind(filename, mimeType) {
81
- const format = detectFileFormat(filename, mimeType);
82
- return format === "unknown" ? "binary" : format;
83
- }
84
- function getFormatLabel(format) {
85
- switch (format) {
86
- case "pdf":
87
- return "PDF";
88
- case "image":
89
- return "Image";
90
- case "video":
91
- return "Video";
92
- case "audio":
93
- return "Audio";
94
- case "csv":
95
- return "CSV";
96
- case "spreadsheet":
97
- return "Spreadsheet";
98
- case "code":
99
- return "Code";
100
- case "json":
101
- return "JSON";
102
- case "yaml":
103
- return "YAML";
104
- case "markdown":
105
- return "Markdown";
106
- case "text":
107
- return "Text";
108
- default:
109
- return "File";
110
- }
111
- }
112
- function getSyntaxLanguage(filename) {
113
- return EXTENSION_TO_SYNTAX_LANGUAGE[fileExtension(filename)];
114
- }
115
- function getCodeLanguage(filename, format) {
116
- if (format === "json" || format === "yaml") return format;
117
- return getSyntaxLanguage(filename);
118
- }
119
-
120
- export {
121
- fileExtension,
122
- detectFileFormat,
123
- resolveFilePreviewKind,
124
- getFormatLabel,
125
- getSyntaxLanguage,
126
- getCodeLanguage
127
- };
@@ -1,19 +0,0 @@
1
- import {
2
- formatDuration
3
- } from "./chunk-4CLN43XT.js";
4
-
5
- // src/run/run-item-primitives.tsx
6
- import { useEffect, useState } from "react";
7
- import { jsx } from "react/jsx-runtime";
8
- function LiveDuration({ startTime }) {
9
- const [elapsed, setElapsed] = useState(Date.now() - startTime);
10
- useEffect(() => {
11
- const id = setInterval(() => setElapsed(Date.now() - startTime), 100);
12
- return () => clearInterval(id);
13
- }, [startTime]);
14
- return /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-neutral-400 dark:text-neutral-500 tabular-nums", children: formatDuration(elapsed) });
15
- }
16
-
17
- export {
18
- LiveDuration
19
- };
@@ -1,437 +0,0 @@
1
- import {
2
- ExpandableContent,
3
- InlineToolItem,
4
- RunRowShell
5
- } from "./chunk-R7B3UWPF.js";
6
- import {
7
- TextShimmer
8
- } from "./chunk-L57WRIND.js";
9
- import {
10
- OpenUIArtifactRenderer
11
- } from "./chunk-BEBXZPHW.js";
12
- import {
13
- formatDuration,
14
- truncateText
15
- } from "./chunk-4CLN43XT.js";
16
- import {
17
- Markdown
18
- } from "./chunk-OL5GYLHV.js";
19
- import {
20
- cn
21
- } from "./chunk-RQHJBTEU.js";
22
-
23
- // src/run/inline-thinking-item.tsx
24
- import { memo, useEffect, useRef, useState } from "react";
25
- import { Brain } from "lucide-react";
26
- import { jsx } from "react/jsx-runtime";
27
- var InlineThinkingItem = memo(
28
- ({
29
- part,
30
- defaultOpen = false,
31
- autoCollapse = true,
32
- className,
33
- contentClassName
34
- }) => {
35
- const [open, setOpen] = useState(defaultOpen);
36
- const autoCollapsedRef = useRef(false);
37
- const startTime = part.time?.start;
38
- const endTime = part.time?.end;
39
- const durationMs = startTime != null && endTime != null ? endTime - startTime : void 0;
40
- const isActive = startTime != null && endTime == null;
41
- const preview = part.text ? truncateText(part.text, 120) : void 0;
42
- useEffect(() => {
43
- if (isActive) {
44
- autoCollapsedRef.current = false;
45
- setOpen(true);
46
- return;
47
- }
48
- if (autoCollapse && !autoCollapsedRef.current && durationMs != null) {
49
- const timer = window.setTimeout(() => {
50
- setOpen(false);
51
- autoCollapsedRef.current = true;
52
- }, 900);
53
- return () => window.clearTimeout(timer);
54
- }
55
- }, [autoCollapse, durationMs, isActive]);
56
- return /* @__PURE__ */ jsx(
57
- RunRowShell,
58
- {
59
- icon: /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5" }),
60
- title: isActive ? /* @__PURE__ */ jsx(TextShimmer, { children: "Thinking\u2026" }) : "Reasoning",
61
- description: preview,
62
- status: isActive ? "running" : "idle",
63
- durationMs,
64
- open,
65
- onOpenChange: setOpen,
66
- className,
67
- children: part.text ? /* @__PURE__ */ jsx(
68
- ExpandableContent,
69
- {
70
- fadeClassName: "from-[var(--md3-surface-container)]",
71
- className: contentClassName ? `px-3 py-3 ${contentClassName}` : "px-3 py-3",
72
- children: /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed text-foreground", children: /* @__PURE__ */ jsx(Markdown, { children: part.text }) })
73
- }
74
- ) : /* @__PURE__ */ jsx("div", { className: "px-3 py-2.5 text-xs text-muted-foreground", children: "No reasoning text provided." })
75
- }
76
- );
77
- }
78
- );
79
- InlineThinkingItem.displayName = "InlineThinkingItem";
80
-
81
- // src/run/run-group.tsx
82
- import { memo as memo2, useMemo } from "react";
83
- import * as Collapsible from "@radix-ui/react-collapsible";
84
- import {
85
- Bot,
86
- Loader2,
87
- ChevronDown,
88
- ChevronRight,
89
- Terminal,
90
- FileEdit,
91
- FileSearch,
92
- Search,
93
- PencilLine,
94
- Globe,
95
- ClipboardList,
96
- Settings,
97
- Sparkles
98
- } from "lucide-react";
99
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
100
- function SpineRow({
101
- accentClassName,
102
- isLast,
103
- children
104
- }) {
105
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-3", children: [
106
- /* @__PURE__ */ jsxs("div", { className: "relative flex justify-center", children: [
107
- !isLast && /* @__PURE__ */ jsx2("span", { className: "absolute top-3.5 bottom-[-0.75rem] left-1/2 w-px -translate-x-1/2 bg-[var(--border-subtle)]" }),
108
- /* @__PURE__ */ jsx2(
109
- "span",
110
- {
111
- className: cn(
112
- "relative mt-2.5 h-[var(--timeline-dot-size,0.5rem)] w-[var(--timeline-dot-size,0.5rem)] rounded-full ring-4 ring-[var(--bg-root)]",
113
- accentClassName
114
- )
115
- }
116
- )
117
- ] }),
118
- /* @__PURE__ */ jsx2("div", { className: "min-w-0 pb-3", children })
119
- ] });
120
- }
121
- var DEFAULT_BRANDING = {
122
- label: "Agent",
123
- accentClass: "text-primary",
124
- bgClass: "bg-[var(--accent-surface-soft)]",
125
- containerBgClass: "bg-muted",
126
- borderClass: "border-border",
127
- iconClass: "",
128
- textClass: "text-primary"
129
- };
130
- var ASSISTANT_SHELL = "min-w-0 flex-1 space-y-3 rounded-[26px] border border-[var(--border-subtle)] bg-[color:color-mix(in_srgb,var(--bg-card)_94%,transparent)] px-5 py-4 shadow-[0_1px_2px_rgba(15,23,42,0.04)]";
131
- function AssistantShell({
132
- branding,
133
- isStreaming,
134
- children
135
- }) {
136
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
137
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs", children: [
138
- /* @__PURE__ */ jsx2("span", { children: branding.label }),
139
- isStreaming ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
140
- /* @__PURE__ */ jsx2(Loader2, { className: "h-3 w-3 animate-spin" }),
141
- "Thinking"
142
- ] }) : null
143
- ] }),
144
- /* @__PURE__ */ jsx2("div", { className: ASSISTANT_SHELL, children })
145
- ] });
146
- }
147
- var CATEGORY_ICON_MAP = {
148
- command: Terminal,
149
- write: FileEdit,
150
- read: FileSearch,
151
- search: Search,
152
- edit: PencilLine,
153
- task: Bot,
154
- web: Globe,
155
- todo: ClipboardList,
156
- other: Settings
157
- };
158
- var CATEGORY_ORDER = [
159
- "command",
160
- "write",
161
- "edit",
162
- "read",
163
- "search",
164
- "web",
165
- "task",
166
- "todo",
167
- "other"
168
- ];
169
- var OPENUI_NODE_TYPES = /* @__PURE__ */ new Set([
170
- "heading",
171
- "text",
172
- "badge",
173
- "stat",
174
- "key_value",
175
- "code",
176
- "markdown",
177
- "table",
178
- "actions",
179
- "separator",
180
- "stack",
181
- "grid",
182
- "card"
183
- ]);
184
- function isOpenUINode(value) {
185
- return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && OPENUI_NODE_TYPES.has(value.type);
186
- }
187
- function extractOpenUISchema(output) {
188
- if (output == null) return null;
189
- if (isOpenUINode(output)) return [output];
190
- if (Array.isArray(output) && output.length > 0 && output.every(isOpenUINode)) {
191
- return output;
192
- }
193
- if (typeof output === "object" && !Array.isArray(output)) {
194
- const obj = output;
195
- for (const key of ["openui", "schema", "ui"]) {
196
- if (obj[key] == null) continue;
197
- const inner = obj[key];
198
- if (typeof inner === "string") {
199
- try {
200
- const parsed = JSON.parse(inner);
201
- return extractOpenUISchema(parsed);
202
- } catch {
203
- continue;
204
- }
205
- }
206
- const nested = extractOpenUISchema(inner);
207
- if (nested) return nested;
208
- }
209
- }
210
- if (typeof output === "string") {
211
- try {
212
- return extractOpenUISchema(JSON.parse(output));
213
- } catch {
214
- return null;
215
- }
216
- }
217
- return null;
218
- }
219
- function getOpenUISummary(output) {
220
- if (!output || typeof output !== "object" || Array.isArray(output)) {
221
- return null;
222
- }
223
- const summary = output.summary;
224
- return typeof summary === "string" && summary.trim() ? summary.trim() : null;
225
- }
226
- function isOpenUITool(part) {
227
- const normalized = part.tool.toLowerCase().replace(/^tool:/, "");
228
- return normalized.includes("openui");
229
- }
230
- function CategoryBadges({ categories }) {
231
- const sorted = useMemo(
232
- () => CATEGORY_ORDER.filter((category) => categories.has(category)),
233
- [categories]
234
- );
235
- if (sorted.length === 0) return null;
236
- return /* @__PURE__ */ jsx2("div", { className: "flex items-center gap-1", children: sorted.map((cat) => {
237
- const Icon = CATEGORY_ICON_MAP[cat] ?? Settings;
238
- return /* @__PURE__ */ jsx2(
239
- "span",
240
- {
241
- title: cat,
242
- className: "flex h-5 w-5 items-center justify-center rounded border border-border text-muted-foreground",
243
- children: /* @__PURE__ */ jsx2(Icon, { className: "h-3 w-3" })
244
- },
245
- cat
246
- );
247
- }) });
248
- }
249
- function renderSummary(run) {
250
- const parts = [];
251
- if (run.stats.toolCount > 0) {
252
- parts.push(`${run.stats.toolCount} tool${run.stats.toolCount === 1 ? "" : "s"}`);
253
- }
254
- if (run.stats.textPartCount > 0) {
255
- parts.push(`${run.stats.textPartCount} response${run.stats.textPartCount === 1 ? "" : "s"}`);
256
- }
257
- if (run.stats.thinkingDurationMs > 0) {
258
- parts.push(`${formatDuration(run.stats.thinkingDurationMs)} thinking`);
259
- }
260
- return parts.join(", ");
261
- }
262
- var RunGroup = memo2(
263
- ({
264
- run,
265
- partMap,
266
- collapsed,
267
- onToggle,
268
- branding = DEFAULT_BRANDING,
269
- renderToolDetail,
270
- headerActions,
271
- renderToolActions
272
- }) => {
273
- const allParts = useMemo(() => {
274
- const parts = [];
275
- for (const msg of run.messages) {
276
- const msgParts = partMap[msg.id] ?? [];
277
- msgParts.forEach((part, index) => {
278
- parts.push({ part, msgId: msg.id, index });
279
- });
280
- }
281
- return parts;
282
- }, [run.messages, partMap]);
283
- const { stats, isStreaming } = run;
284
- const hasRenderableParts = allParts.some(({ part }) => {
285
- if (part.type === "tool" || part.type === "reasoning") {
286
- return true;
287
- }
288
- return part.type === "text" && !part.synthetic && part.text.trim().length > 0;
289
- });
290
- if (!hasRenderableParts) {
291
- if (!isStreaming) {
292
- return null;
293
- }
294
- return /* @__PURE__ */ jsx2(AssistantShell, { branding, isStreaming: true, children: /* @__PURE__ */ jsx2("div", { className: "flex items-center gap-2 px-0.5 py-0.5 text-sm text-[var(--text-muted)]", children: /* @__PURE__ */ jsxs("span", { className: "flex gap-[5px]", children: [
295
- /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "0ms" } }),
296
- /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "150ms" } }),
297
- /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "300ms" } })
298
- ] }) }) });
299
- }
300
- const showTraceChrome = allParts.some(({ part }) => {
301
- if (part.type === "reasoning") {
302
- return true;
303
- }
304
- if (part.type === "tool") {
305
- return !isOpenUITool(part);
306
- }
307
- return false;
308
- });
309
- if (!showTraceChrome) {
310
- return /* @__PURE__ */ jsx2(AssistantShell, { branding, isStreaming, children: allParts.map(({ part, msgId, index }) => {
311
- const key = `${msgId}-${index}`;
312
- if (part.type === "tool" && isOpenUITool(part)) {
313
- const toolPart = part;
314
- const schema = extractOpenUISchema(toolPart.state.output);
315
- const summary = getOpenUISummary(toolPart.state.output);
316
- if (toolPart.state.status === "completed" && schema) {
317
- return /* @__PURE__ */ jsxs(
318
- "div",
319
- {
320
- className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]",
321
- children: [
322
- summary ? /* @__PURE__ */ jsx2("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3 text-sm leading-6 text-foreground", children: summary }) : null,
323
- /* @__PURE__ */ jsx2("div", { className: "p-4", children: /* @__PURE__ */ jsx2(OpenUIArtifactRenderer, { schema }) })
324
- ]
325
- },
326
- key
327
- );
328
- }
329
- if (toolPart.state.status === "running") {
330
- return /* @__PURE__ */ jsxs(
331
- "div",
332
- {
333
- className: "flex items-center gap-2 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)] px-4 py-3 text-sm text-muted-foreground",
334
- children: [
335
- /* @__PURE__ */ jsx2(Loader2, { className: "h-4 w-4 animate-spin text-primary" }),
336
- "Building view\u2026"
337
- ]
338
- },
339
- key
340
- );
341
- }
342
- }
343
- if (part.type === "text" && !part.synthetic && part.text.trim()) {
344
- return /* @__PURE__ */ jsx2("div", { className: "px-0.5", children: /* @__PURE__ */ jsx2(Markdown, { className: "tangle-prose text-[15px] leading-7 text-[var(--text-primary)]", children: part.text }) }, key);
345
- }
346
- return null;
347
- }) });
348
- }
349
- const rows = allParts.filter(({ part }) => {
350
- if (part.type === "tool" || part.type === "reasoning") return true;
351
- return part.type === "text" && !part.synthetic && part.text.trim().length > 0;
352
- });
353
- const dotAccent = (part) => {
354
- if (part.type === "reasoning") return "bg-[var(--brand-glow)]";
355
- if (part.type === "text") return "bg-primary";
356
- return "bg-[var(--border-hover)]";
357
- };
358
- return /* @__PURE__ */ jsx2(Collapsible.Root, { open: !collapsed, onOpenChange: () => onToggle(), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
359
- /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
360
- /* @__PURE__ */ jsx2(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
361
- "button",
362
- {
363
- type: "button",
364
- className: "group flex min-w-0 flex-1 items-center gap-2 rounded-md px-1 py-0.5 text-left transition-colors hover:bg-[var(--surface-container-high)]/40",
365
- children: [
366
- collapsed ? /* @__PURE__ */ jsx2(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
367
- /* @__PURE__ */ jsx2("span", { className: cn("font-semibold text-sm", branding.textClass), children: branding.label }),
368
- renderSummary(run) ? /* @__PURE__ */ jsx2("span", { className: "text-[11px] text-muted-foreground", children: renderSummary(run) }) : null,
369
- collapsed && run.summaryText ? /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate text-[11px] text-foreground/70", children: run.summaryText }) : null,
370
- /* @__PURE__ */ jsxs("span", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
371
- /* @__PURE__ */ jsx2(CategoryBadges, { categories: stats.toolCategories }),
372
- isStreaming ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-px text-[10px] font-semibold uppercase text-[var(--accent-text)]", children: [
373
- /* @__PURE__ */ jsx2(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
374
- "Running"
375
- ] }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground", children: [
376
- /* @__PURE__ */ jsx2(Sparkles, { className: "h-2.5 w-2.5" }),
377
- "Done"
378
- ] })
379
- ] })
380
- ]
381
- }
382
- ) }),
383
- headerActions ? /* @__PURE__ */ jsx2("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-1.5 pt-1", children: headerActions }) : null
384
- ] }),
385
- collapsed && run.summaryText ? /* @__PURE__ */ jsx2("div", { className: "line-clamp-2 pl-6 text-sm leading-6 text-muted-foreground", children: run.summaryText }) : null,
386
- /* @__PURE__ */ jsx2(Collapsible.Content, { className: "overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp", children: /* @__PURE__ */ jsx2("div", { className: "pt-1.5", children: rows.map(({ part, msgId, index }, rowIndex) => {
387
- const key = `${msgId}-${index}`;
388
- const isLast = rowIndex === rows.length - 1;
389
- let node = null;
390
- if (part.type === "tool") {
391
- if (isOpenUITool(part)) {
392
- const toolPart = part;
393
- const schema = extractOpenUISchema(toolPart.state.output);
394
- const summary = getOpenUISummary(toolPart.state.output);
395
- if (toolPart.state.status === "completed" && schema) {
396
- node = /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: [
397
- summary ? /* @__PURE__ */ jsx2("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3 text-sm leading-6 text-foreground", children: summary }) : null,
398
- /* @__PURE__ */ jsx2("div", { className: "p-4", children: /* @__PURE__ */ jsx2(OpenUIArtifactRenderer, { schema }) })
399
- ] });
400
- } else if (toolPart.state.status === "running") {
401
- node = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)] px-4 py-3 text-sm text-muted-foreground", children: [
402
- /* @__PURE__ */ jsx2(Loader2, { className: "h-4 w-4 animate-spin text-primary" }),
403
- "Building view\u2026"
404
- ] });
405
- }
406
- }
407
- if (node === null) {
408
- node = /* @__PURE__ */ jsx2(
409
- InlineToolItem,
410
- {
411
- part,
412
- renderToolDetail,
413
- actions: renderToolActions?.(part, {
414
- run,
415
- messageId: msgId,
416
- partIndex: index
417
- })
418
- }
419
- );
420
- }
421
- } else if (part.type === "reasoning") {
422
- node = /* @__PURE__ */ jsx2(InlineThinkingItem, { part, defaultOpen: isStreaming });
423
- } else if (part.type === "text" && !part.synthetic && part.text.trim()) {
424
- node = /* @__PURE__ */ jsx2("div", { className: "px-1 py-0.5", children: /* @__PURE__ */ jsx2(Markdown, { className: "tangle-prose text-[15px] leading-7", children: part.text }) });
425
- }
426
- if (!node) return null;
427
- return /* @__PURE__ */ jsx2(SpineRow, { accentClassName: dotAccent(part), isLast, children: node }, key);
428
- }) }) })
429
- ] }) });
430
- }
431
- );
432
- RunGroup.displayName = "RunGroup";
433
-
434
- export {
435
- InlineThinkingItem,
436
- RunGroup
437
- };