@tangle-network/ui 11.10.0 → 11.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +4 -1
  3. package/dist/active-sessions-store-Gt1R0rFG.js +262 -0
  4. package/dist/{active-sessions-store-CeOmXgv5.d.ts → active-sessions-store-nl70ZnMC.d.ts} +40 -41
  5. package/dist/artifact-pane-BL_DFWNl.d.ts +32 -0
  6. package/dist/artifact-pane-DMXT9a8U.js +70 -0
  7. package/dist/auth-DOETfnd9.js +154 -0
  8. package/dist/auth.d.ts +2 -74
  9. package/dist/auth.js +2 -16
  10. package/dist/branding-26d5ARIr.d.ts +14 -0
  11. package/dist/button-C87nEe2R.js +78 -0
  12. package/dist/button-yoIv77e2.d.ts +16 -0
  13. package/dist/chat-D4jAfEmj.js +667 -0
  14. package/dist/chat.d.ts +2 -201
  15. package/dist/chat.js +2 -31
  16. package/dist/code-block-B36KVUSN.js +165 -0
  17. package/dist/code-block-B9miUPht.d.ts +23 -0
  18. package/dist/diff-preview-BcK3nRXb.js +533 -0
  19. package/dist/document-editor-pane-BcoABlhn.d.ts +131 -0
  20. package/dist/document-editor-pane-BxlPjaTP.js +1287 -0
  21. package/dist/dropdown-menu-BpcLa5vF.js +101 -0
  22. package/dist/editor.d.ts +76 -78
  23. package/dist/editor.js +2 -34
  24. package/dist/file-format-BgXbr-Ib.js +160 -0
  25. package/dist/files-Bug33qCl.js +743 -0
  26. package/dist/files.d.ts +2 -243
  27. package/dist/files.js +3 -41
  28. package/dist/focus-BcE_SHqz.js +57 -0
  29. package/dist/format-DfcLWqMa.js +54 -0
  30. package/dist/hooks.d.ts +30 -37
  31. package/dist/hooks.js +111 -46
  32. package/dist/index-2UntyjBb.d.ts +52 -0
  33. package/dist/index-BgUHilZm.d.ts +108 -0
  34. package/dist/index-COgqsFAQ.d.ts +42 -0
  35. package/dist/index-CPDET_s1.d.ts +549 -0
  36. package/dist/index-CUhfHT_V.d.ts +204 -0
  37. package/dist/index-Cg6gYAqh.d.ts +73 -0
  38. package/dist/index-Cq-EJzqW.d.ts +16 -0
  39. package/dist/index-DhYmSaLF.d.ts +245 -0
  40. package/dist/index-DjKxO357.d.ts +128 -0
  41. package/dist/index.d.ts +26 -43
  42. package/dist/index.js +35 -472
  43. package/dist/markdown-BGqicV82.js +45 -0
  44. package/dist/markdown.d.ts +3 -18
  45. package/dist/markdown.js +3 -15
  46. package/dist/message-vhUI0c5G.d.ts +16 -0
  47. package/dist/nav.d.ts +6 -8
  48. package/dist/nav.js +29 -11
  49. package/dist/openui-artifact-renderer-D3E5bIAI.d.ts +114 -0
  50. package/dist/openui-artifact-renderer-DrU1AdVk.js +266 -0
  51. package/dist/openui.d.ts +2 -115
  52. package/dist/openui.js +2 -13
  53. package/dist/parts-5mhy9yJ3.d.ts +37 -0
  54. package/dist/primitives-Cb8GGVKr.js +1239 -0
  55. package/dist/primitives.d.ts +5 -525
  56. package/dist/primitives.js +9 -212
  57. package/dist/redaction-CGGB2ENG.js +74 -0
  58. package/dist/redaction.d.ts +2 -42
  59. package/dist/redaction.js +2 -7
  60. package/dist/run-OyWmIDqu.d.ts +41 -0
  61. package/dist/run-ZsIKPA6J.js +17 -0
  62. package/dist/run-group-BACLbCFl.js +410 -0
  63. package/dist/run.d.ts +3 -126
  64. package/dist/run.js +5 -40
  65. package/dist/sdk-hooks.d.ts +2 -285
  66. package/dist/sdk-hooks.js +3 -36
  67. package/dist/stores.d.ts +13 -14
  68. package/dist/stores.js +34 -76
  69. package/dist/table-Bss73DhB.js +146 -0
  70. package/dist/tabs-BVHR6NkO.js +40 -0
  71. package/dist/text-shimmer-BUUo6I-g.js +64 -0
  72. package/dist/tool-call-feed-BeB1_4pX.d.ts +47 -0
  73. package/dist/tool-call-feed-Djt2q11V.js +109 -0
  74. package/dist/tool-call-step-DNebqhmX.js +434 -0
  75. package/dist/tool-display-BAuAVa43.js +158 -0
  76. package/dist/{tool-display-z4JcDmMQ.d.ts → tool-display-DgmL5rIU.d.ts} +16 -16
  77. package/dist/tool-previews.d.ts +2 -48
  78. package/dist/tool-previews.js +2 -23
  79. package/dist/types.d.ts +6 -19
  80. package/dist/types.js +0 -1
  81. package/dist/use-auto-scroll-C5Pjeqon.js +153 -0
  82. package/dist/use-sse-stream-BVgO1QBN.js +884 -0
  83. package/dist/use-sse-stream-Dm6R5YWz.d.ts +282 -0
  84. package/dist/utils-Bl_CZ0Qp.js +37 -0
  85. package/dist/{chunk-RQHJBTEU.js → utils-C_uf36nf.js} +4 -6
  86. package/dist/utils.d.ts +2 -104
  87. package/dist/utils.js +6 -44
  88. package/package.json +39 -41
  89. package/src/lib/focus.ts +2 -1
  90. package/dist/artifact-pane-DpuWcAiF.d.ts +0 -33
  91. package/dist/button-CMQuQEW_.d.ts +0 -17
  92. package/dist/chunk-34A66VBG.js +0 -214
  93. package/dist/chunk-3OI2QKFD.js +0 -0
  94. package/dist/chunk-3XXBZL53.js +0 -174
  95. package/dist/chunk-42PAH5D2.js +0 -112
  96. package/dist/chunk-4CLN43XT.js +0 -45
  97. package/dist/chunk-55WHV7SS.js +0 -1604
  98. package/dist/chunk-565EATZZ.js +0 -156
  99. package/dist/chunk-5Z5ZYMOJ.js +0 -0
  100. package/dist/chunk-6BGQA4BQ.js +0 -0
  101. package/dist/chunk-BEBXZPHW.js +0 -299
  102. package/dist/chunk-C5WF4WMV.js +0 -734
  103. package/dist/chunk-HFL6R6IF.js +0 -37
  104. package/dist/chunk-HGML45QH.js +0 -104
  105. package/dist/chunk-HMAPIH7L.js +0 -595
  106. package/dist/chunk-K5XFRUS4.js +0 -1401
  107. package/dist/chunk-KFQGHD73.js +0 -198
  108. package/dist/chunk-L57WRIND.js +0 -59
  109. package/dist/chunk-LTEKI7YJ.js +0 -59
  110. package/dist/chunk-M3QZK62R.js +0 -233
  111. package/dist/chunk-ND3ZFXQK.js +0 -179
  112. package/dist/chunk-OEX7NZE3.js +0 -321
  113. package/dist/chunk-OL5GYLHV.js +0 -60
  114. package/dist/chunk-QGFYBNSO.js +0 -133
  115. package/dist/chunk-R7B3UWPF.js +0 -550
  116. package/dist/chunk-R7SUY4E3.js +0 -65
  117. package/dist/chunk-REJESC5U.js +0 -117
  118. package/dist/chunk-RQGKSCEZ.js +0 -0
  119. package/dist/chunk-SNLR2AEA.js +0 -40
  120. package/dist/chunk-WKWBTL2V.js +0 -15
  121. package/dist/chunk-X7CU776B.js +0 -1048
  122. package/dist/chunk-XU3HB5QL.js +0 -127
  123. package/dist/chunk-YTO5V6QS.js +0 -19
  124. package/dist/chunk-YU4E5J2N.js +0 -437
  125. package/dist/chunk-YZ6AK25N.js +0 -886
  126. package/dist/code-block-0kSpWMnf.d.ts +0 -25
  127. package/dist/document-editor-pane-IAEQn_Dl.d.ts +0 -128
  128. package/dist/document-editor-pane-QHDOBA43.js +0 -13
  129. package/dist/message-BHWbxBtT.d.ts +0 -15
  130. package/dist/parts-dj7AcUg0.d.ts +0 -36
  131. package/dist/run-PfLmDAox.d.ts +0 -41
  132. 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
- };