@tangle-network/ui 11.6.0 → 11.8.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.
- package/CHANGELOG.md +12 -0
- package/README.md +43 -0
- package/dist/chat.d.ts +18 -8
- package/dist/chat.js +9 -7
- package/dist/chunk-4CLN43XT.js +45 -0
- package/dist/{chunk-AZWDI2JG.js → chunk-565EATZZ.js} +1 -1
- package/dist/{chunk-XROQW5J7.js → chunk-BWOUSEHM.js} +1 -1
- package/dist/{chunk-J2G7KCYH.js → chunk-KNYSKNZX.js} +113 -69
- package/dist/chunk-L57WRIND.js +59 -0
- package/dist/{chunk-ULDNFLIM.js → chunk-ND3ZFXQK.js} +11 -58
- package/dist/{chunk-AAUNOHVL.js → chunk-NWECTSOH.js} +1 -1
- package/dist/{chunk-R5GVQDL3.js → chunk-OXZRCXJK.js} +9 -7
- package/dist/{chunk-XPYPZMYT.js → chunk-Q7ZR6LSD.js} +1 -1
- package/dist/{chunk-RKC3GXHE.js → chunk-X53RZSX6.js} +99 -104
- package/dist/{chunk-PLWRAS5Z.js → chunk-XGOWUDDW.js} +270 -106
- package/dist/{chunk-ZRVH3WCA.js → chunk-XU3HB5QL.js} +21 -1
- package/dist/chunk-YTO5V6QS.js +19 -0
- package/dist/files.d.ts +41 -12
- package/dist/files.js +13 -5
- package/dist/hooks.js +9 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -24
- package/dist/primitives.d.ts +15 -1
- package/dist/primitives.js +5 -1
- package/dist/run.d.ts +22 -17
- package/dist/run.js +11 -8
- package/dist/sdk-hooks.js +9 -7
- package/dist/tool-previews.js +2 -2
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +6 -4
- package/package.json +1 -1
- package/src/chat/agent-timeline.stories.tsx +163 -10
- package/src/chat/agent-timeline.test.tsx +114 -7
- package/src/chat/agent-timeline.tsx +120 -158
- package/src/chat/chat-container.test.tsx +59 -0
- package/src/chat/user-message.test.tsx +33 -0
- package/src/chat/user-message.tsx +13 -8
- package/src/files/file-artifact-pane.stories.tsx +149 -0
- package/src/files/file-artifact-pane.test.tsx +192 -0
- package/src/files/file-artifact-pane.tsx +6 -1
- package/src/files/file-format.ts +42 -4
- package/src/files/file-preview-kind.test.ts +109 -0
- package/src/files/file-preview.tsx +315 -132
- package/src/files/index.ts +8 -1
- package/src/primitives/index.ts +3 -0
- package/src/primitives/text-shimmer.test.tsx +34 -0
- package/src/primitives/text-shimmer.tsx +82 -0
- package/src/run/inline-thinking-item.stories.tsx +2 -2
- package/src/run/inline-thinking-item.tsx +2 -2
- package/src/run/inline-tool-item.test.tsx +76 -0
- package/src/run/inline-tool-item.tsx +9 -7
- package/src/run/run-group.tsx +4 -3
- package/src/run/run-row-shell.test.tsx +74 -4
- package/src/run/run-row-shell.tsx +81 -53
- package/src/run/tool-call-step.tsx +9 -7
- package/src/utils/tool-display.test.ts +53 -0
- package/src/utils/tool-display.ts +16 -15
- package/dist/chunk-LQS34IGP.js +0 -0
- /package/dist/{chunk-EJ5NBW7V.js → chunk-LDLOJKPC.js} +0 -0
|
@@ -18,10 +18,6 @@ function extractCommand(input) {
|
|
|
18
18
|
function extractFilePath(input) {
|
|
19
19
|
return extractString(input, "file_path") ?? extractString(input, "path") ?? extractString(input, "filePath") ?? extractString(input, "file");
|
|
20
20
|
}
|
|
21
|
-
function cleanPath(path) {
|
|
22
|
-
const parts = path.split("/");
|
|
23
|
-
return parts.length > 3 ? ".../" + parts.slice(-2).join("/") : path;
|
|
24
|
-
}
|
|
25
21
|
var TOOL_CATEGORY_ICONS = {
|
|
26
22
|
command: "terminal",
|
|
27
23
|
write: "file-plus",
|
|
@@ -87,7 +83,7 @@ function getToolDisplayMetadata(part) {
|
|
|
87
83
|
case "command":
|
|
88
84
|
case "execute":
|
|
89
85
|
return {
|
|
90
|
-
title: "
|
|
86
|
+
title: "Shell",
|
|
91
87
|
description: command ? truncateCommand(command) : void 0,
|
|
92
88
|
displayVariant: "command",
|
|
93
89
|
commandSnippet: command
|
|
@@ -96,7 +92,7 @@ function getToolDisplayMetadata(part) {
|
|
|
96
92
|
case "write_file":
|
|
97
93
|
case "create_file":
|
|
98
94
|
return {
|
|
99
|
-
title:
|
|
95
|
+
title: "Write",
|
|
100
96
|
description: filePath,
|
|
101
97
|
displayVariant: "write-file",
|
|
102
98
|
targetPath: filePath
|
|
@@ -104,7 +100,7 @@ function getToolDisplayMetadata(part) {
|
|
|
104
100
|
case "edit":
|
|
105
101
|
case "patch":
|
|
106
102
|
return {
|
|
107
|
-
title:
|
|
103
|
+
title: "Edit",
|
|
108
104
|
description: filePath,
|
|
109
105
|
hasDiffOutput: true,
|
|
110
106
|
diffFilePath: filePath,
|
|
@@ -115,7 +111,7 @@ function getToolDisplayMetadata(part) {
|
|
|
115
111
|
case "read_file":
|
|
116
112
|
case "cat":
|
|
117
113
|
return {
|
|
118
|
-
title:
|
|
114
|
+
title: "Read",
|
|
119
115
|
description: filePath,
|
|
120
116
|
displayVariant: "read-file",
|
|
121
117
|
targetPath: filePath
|
|
@@ -125,7 +121,7 @@ function getToolDisplayMetadata(part) {
|
|
|
125
121
|
case "rg": {
|
|
126
122
|
const pattern = extractString(input, "pattern");
|
|
127
123
|
return {
|
|
128
|
-
title:
|
|
124
|
+
title: "Search",
|
|
129
125
|
description: pattern,
|
|
130
126
|
displayVariant: "grep"
|
|
131
127
|
};
|
|
@@ -135,7 +131,7 @@ function getToolDisplayMetadata(part) {
|
|
|
135
131
|
case "ls": {
|
|
136
132
|
const pattern = extractString(input, "pattern");
|
|
137
133
|
return {
|
|
138
|
-
title:
|
|
134
|
+
title: "Find",
|
|
139
135
|
description: pattern,
|
|
140
136
|
displayVariant: "glob"
|
|
141
137
|
};
|
|
@@ -145,8 +141,8 @@ function getToolDisplayMetadata(part) {
|
|
|
145
141
|
case "fetch": {
|
|
146
142
|
const query = extractString(input, "query") ?? extractString(input, "url");
|
|
147
143
|
return {
|
|
148
|
-
title:
|
|
149
|
-
description: query,
|
|
144
|
+
title: name === "web_search" ? "Web search" : "Fetch",
|
|
145
|
+
description: query ? truncateCommand(query) : void 0,
|
|
150
146
|
displayVariant: "web-search"
|
|
151
147
|
};
|
|
152
148
|
}
|
|
@@ -155,8 +151,8 @@ function getToolDisplayMetadata(part) {
|
|
|
155
151
|
case "spawn": {
|
|
156
152
|
const desc = extractString(input, "description") ?? extractString(input, "prompt");
|
|
157
153
|
return {
|
|
158
|
-
title:
|
|
159
|
-
description: desc
|
|
154
|
+
title: "Task",
|
|
155
|
+
description: desc ? truncateCommand(desc) : void 0
|
|
160
156
|
};
|
|
161
157
|
}
|
|
162
158
|
default:
|
|
@@ -175,52 +171,9 @@ function getToolErrorText(part, fallback) {
|
|
|
175
171
|
return part.state.error || fallback;
|
|
176
172
|
}
|
|
177
173
|
|
|
178
|
-
// src/utils/format.ts
|
|
179
|
-
function formatDuration(ms) {
|
|
180
|
-
if (ms < 1e3) return "<1s";
|
|
181
|
-
const seconds = Math.floor(ms / 1e3);
|
|
182
|
-
if (seconds < 60) return `${seconds}s`;
|
|
183
|
-
const minutes = Math.floor(seconds / 60);
|
|
184
|
-
const remaining = seconds % 60;
|
|
185
|
-
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
186
|
-
}
|
|
187
|
-
function truncateText(text, max) {
|
|
188
|
-
const cleaned = text.replace(/\s+/g, " ").trim();
|
|
189
|
-
if (cleaned.length <= max) return cleaned;
|
|
190
|
-
return cleaned.slice(0, max).trim() + "...";
|
|
191
|
-
}
|
|
192
|
-
function formatUptime(ms) {
|
|
193
|
-
if (!Number.isFinite(ms) || ms < 0) return "\u2014";
|
|
194
|
-
const totalSeconds = Math.floor(ms / 1e3);
|
|
195
|
-
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
196
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
197
|
-
const seconds = totalSeconds % 60;
|
|
198
|
-
if (minutes < 60) return `${minutes}m ${seconds}s`;
|
|
199
|
-
const hours = Math.floor(minutes / 60);
|
|
200
|
-
const remMinutes = minutes % 60;
|
|
201
|
-
if (hours < 24) return `${hours}h ${remMinutes}m`;
|
|
202
|
-
const days = Math.floor(hours / 24);
|
|
203
|
-
const remHours = hours % 24;
|
|
204
|
-
return `${days}d ${remHours}h`;
|
|
205
|
-
}
|
|
206
|
-
function formatBytes(bytes) {
|
|
207
|
-
if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
|
|
208
|
-
if (bytes < 1024) return `${Math.round(bytes)} B`;
|
|
209
|
-
const kb = bytes / 1024;
|
|
210
|
-
if (kb < 1024) return `${kb < 10 ? kb.toFixed(1) : Math.round(kb)} KB`;
|
|
211
|
-
const mb = kb / 1024;
|
|
212
|
-
if (mb < 1024) return `${mb < 10 ? mb.toFixed(1) : Math.round(mb)} MB`;
|
|
213
|
-
const gb = mb / 1024;
|
|
214
|
-
return `${gb < 10 ? gb.toFixed(2) : gb.toFixed(1)} GB`;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
174
|
export {
|
|
218
175
|
TOOL_CATEGORY_ICONS,
|
|
219
176
|
getToolCategory,
|
|
220
177
|
getToolDisplayMetadata,
|
|
221
|
-
getToolErrorText
|
|
222
|
-
formatDuration,
|
|
223
|
-
truncateText,
|
|
224
|
-
formatUptime,
|
|
225
|
-
formatBytes
|
|
178
|
+
getToolErrorText
|
|
226
179
|
};
|
|
@@ -2,14 +2,17 @@ import {
|
|
|
2
2
|
ExpandableContent,
|
|
3
3
|
InlineToolItem,
|
|
4
4
|
RunRowShell
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KNYSKNZX.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "./chunk-ULDNFLIM.js";
|
|
7
|
+
TextShimmer
|
|
8
|
+
} from "./chunk-L57WRIND.js";
|
|
10
9
|
import {
|
|
11
10
|
OpenUIArtifactRenderer
|
|
12
11
|
} from "./chunk-3M7BPSSW.js";
|
|
12
|
+
import {
|
|
13
|
+
formatDuration,
|
|
14
|
+
truncateText
|
|
15
|
+
} from "./chunk-4CLN43XT.js";
|
|
13
16
|
import {
|
|
14
17
|
Markdown
|
|
15
18
|
} from "./chunk-P5F43A65.js";
|
|
@@ -54,10 +57,9 @@ var InlineThinkingItem = memo(
|
|
|
54
57
|
RunRowShell,
|
|
55
58
|
{
|
|
56
59
|
icon: /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5" }),
|
|
57
|
-
title: isActive ? "Thinking\u2026" : "Reasoning",
|
|
60
|
+
title: isActive ? /* @__PURE__ */ jsx(TextShimmer, { children: "Thinking\u2026" }) : "Reasoning",
|
|
58
61
|
description: preview,
|
|
59
62
|
status: isActive ? "running" : "idle",
|
|
60
|
-
startTime,
|
|
61
63
|
durationMs,
|
|
62
64
|
open,
|
|
63
65
|
onOpenChange: setOpen,
|
|
@@ -107,7 +109,7 @@ function SpineRow({
|
|
|
107
109
|
"span",
|
|
108
110
|
{
|
|
109
111
|
className: cn(
|
|
110
|
-
"relative mt-
|
|
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)]",
|
|
111
113
|
accentClassName
|
|
112
114
|
)
|
|
113
115
|
}
|
|
@@ -2,18 +2,18 @@ import {
|
|
|
2
2
|
useAutoScroll,
|
|
3
3
|
useRunCollapseState,
|
|
4
4
|
useRunGroups
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-565EATZZ.js";
|
|
6
6
|
import {
|
|
7
7
|
InlineThinkingItem,
|
|
8
8
|
RunGroup
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-OXZRCXJK.js";
|
|
10
10
|
import {
|
|
11
11
|
ToolCallGroup,
|
|
12
12
|
ToolCallStep
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KNYSKNZX.js";
|
|
14
14
|
import {
|
|
15
15
|
getToolDisplayMetadata
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ND3ZFXQK.js";
|
|
17
17
|
import {
|
|
18
18
|
OpenUIArtifactRenderer
|
|
19
19
|
} from "./chunk-3M7BPSSW.js";
|
|
@@ -45,10 +45,17 @@ var UserMessage = memo(
|
|
|
45
45
|
({ message: _message, parts, content, timestamp, actions }) => {
|
|
46
46
|
const text = content ?? (parts ?? []).filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
47
47
|
if (!text.trim()) return null;
|
|
48
|
-
return /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs("div", { className: "flex max-w-[78%] flex-col items-end gap-2", children: [
|
|
49
|
-
/* @__PURE__ */ jsxs("div", { className: "w-full rounded-2xl
|
|
50
|
-
timestamp ? /* @__PURE__ */ jsx(
|
|
51
|
-
|
|
48
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs("div", { className: "group flex max-w-[78%] flex-col items-end gap-2", children: [
|
|
49
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-full rounded-2xl bg-muted/50 px-4 py-3", children: [
|
|
50
|
+
timestamp ? /* @__PURE__ */ jsx(
|
|
51
|
+
"span",
|
|
52
|
+
{
|
|
53
|
+
"data-user-message-time": "",
|
|
54
|
+
className: "pointer-events-none absolute right-full top-1/2 mr-3 -translate-y-1/2 whitespace-nowrap text-[var(--font-size-xs)] text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100",
|
|
55
|
+
children: formatTime(timestamp)
|
|
56
|
+
}
|
|
57
|
+
) : null,
|
|
58
|
+
/* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap text-[var(--font-size-base)] leading-[1.5] text-foreground", children: text })
|
|
52
59
|
] }),
|
|
53
60
|
actions ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-end gap-1.5 text-xs text-muted-foreground", children: actions }) : null
|
|
54
61
|
] }) });
|
|
@@ -146,55 +153,56 @@ function ThinkingIndicator({ className }) {
|
|
|
146
153
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
147
154
|
var TONE_STYLES = {
|
|
148
155
|
default: {
|
|
149
|
-
dot: "bg-[var(--border-hover)]",
|
|
150
156
|
card: "border-border bg-card",
|
|
151
157
|
text: "text-foreground",
|
|
152
158
|
icon: CircleDot
|
|
153
159
|
},
|
|
154
160
|
info: {
|
|
155
|
-
dot: "bg-[var(--surface-info-text)]",
|
|
156
161
|
card: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)]",
|
|
157
162
|
text: "text-[var(--surface-info-text)]",
|
|
158
163
|
icon: Info
|
|
159
164
|
},
|
|
160
165
|
success: {
|
|
161
|
-
dot: "bg-[var(--surface-success-text)]",
|
|
162
166
|
card: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]",
|
|
163
167
|
text: "text-[var(--surface-success-text)]",
|
|
164
168
|
icon: CheckCircle2
|
|
165
169
|
},
|
|
166
170
|
warning: {
|
|
167
|
-
dot: "bg-[var(--surface-warning-text)]",
|
|
168
171
|
card: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)]",
|
|
169
172
|
text: "text-[var(--surface-warning-text)]",
|
|
170
173
|
icon: AlertTriangle
|
|
171
174
|
},
|
|
172
175
|
error: {
|
|
173
|
-
dot: "bg-[var(--surface-danger-text)]",
|
|
174
176
|
card: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]",
|
|
175
177
|
text: "text-[var(--surface-danger-text)]",
|
|
176
178
|
icon: AlertTriangle
|
|
177
179
|
}
|
|
178
180
|
};
|
|
179
|
-
function
|
|
180
|
-
return
|
|
181
|
+
function stepKind(item) {
|
|
182
|
+
if (item.kind === "message") return item.role === "user" ? "user" : "prose";
|
|
183
|
+
if (item.kind === "status" || item.kind === "artifact") return "card";
|
|
184
|
+
return "tool";
|
|
181
185
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
] }),
|
|
189
|
-
/* @__PURE__ */ jsx4("div", { className: "min-w-0 pb-3", children })
|
|
190
|
-
] });
|
|
186
|
+
function spacingBefore(prev, next) {
|
|
187
|
+
if (prev === void 0) return "";
|
|
188
|
+
if (prev === "user" || next === "user") return "mt-4";
|
|
189
|
+
if (prev === "card" || next === "card") return "mt-2";
|
|
190
|
+
if (prev === "tool" || next === "tool") return "mt-1";
|
|
191
|
+
return "mt-3";
|
|
191
192
|
}
|
|
193
|
+
var ROW_BLEED = "-mx-3";
|
|
192
194
|
function AssistantMessage({ item }) {
|
|
193
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
194
|
-
item.
|
|
195
|
-
item.
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
196
|
+
item.content && /* @__PURE__ */ jsx4(Markdown, { className: "tangle-prose text-[var(--font-size-base)] leading-[1.5]", children: item.content }),
|
|
197
|
+
item.isStreaming && /* @__PURE__ */ jsx4(
|
|
198
|
+
"span",
|
|
199
|
+
{
|
|
200
|
+
"aria-hidden": true,
|
|
201
|
+
"data-streaming-caret": "",
|
|
202
|
+
className: "ml-0.5 inline-block h-[1em] w-0.5 animate-pulse rounded-full bg-muted-foreground align-text-bottom"
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
item.toolCalls && /* @__PURE__ */ jsx4("div", { className: "mt-1", children: item.toolCalls }),
|
|
198
206
|
item.after && /* @__PURE__ */ jsx4("div", { className: "mt-3 border-t border-border pt-3", children: item.after })
|
|
199
207
|
] });
|
|
200
208
|
}
|
|
@@ -252,101 +260,88 @@ function AgentTimeline({
|
|
|
252
260
|
}
|
|
253
261
|
const renderedItems = isThinking ? [...items, { id: "__thinking__", kind: "custom", content: /* @__PURE__ */ jsx4(ThinkingIndicator, {}) }] : items;
|
|
254
262
|
const isUserMessage = (item) => item.kind === "message" && item.role === "user";
|
|
255
|
-
const
|
|
263
|
+
const stepItems = renderedItems.filter((item) => !isUserMessage(item));
|
|
256
264
|
const limit = collapseAfter ?? Infinity;
|
|
257
|
-
const collapsible =
|
|
265
|
+
const collapsible = stepItems.length > limit;
|
|
258
266
|
const collapsed = collapsible && !expanded;
|
|
259
267
|
let renderList = renderedItems;
|
|
260
268
|
let hiddenCount = 0;
|
|
261
269
|
if (collapsed) {
|
|
262
270
|
const visible = [];
|
|
263
|
-
let
|
|
271
|
+
let stepCount = 0;
|
|
264
272
|
for (const item of renderedItems) {
|
|
265
|
-
if (
|
|
273
|
+
if (stepCount >= limit) break;
|
|
266
274
|
visible.push(item);
|
|
267
|
-
if (!isUserMessage(item))
|
|
275
|
+
if (!isUserMessage(item)) stepCount += 1;
|
|
268
276
|
}
|
|
269
277
|
renderList = visible;
|
|
270
|
-
hiddenCount =
|
|
278
|
+
hiddenCount = stepItems.length - limit;
|
|
271
279
|
}
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
actions: item.part ? renderToolActions?.(item.part) : void 0
|
|
295
|
-
}
|
|
296
|
-
) }, item.id);
|
|
297
|
-
}
|
|
298
|
-
if (item.kind === "tool_group") {
|
|
299
|
-
return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", dotClassName: CARD_ROW_DOT, children: /* @__PURE__ */ jsx4(ToolCallGroup, { title: item.title, children: item.calls.map((call, callIndex) => {
|
|
300
|
-
const part = item.parts?.[callIndex];
|
|
301
|
-
return /* @__PURE__ */ jsx4(
|
|
302
|
-
ToolCallStep,
|
|
303
|
-
{
|
|
304
|
-
type: call.type,
|
|
305
|
-
label: call.label,
|
|
306
|
-
status: call.status,
|
|
307
|
-
detail: call.detail,
|
|
308
|
-
output: call.output,
|
|
309
|
-
duration: call.duration,
|
|
310
|
-
part,
|
|
311
|
-
actions: part ? renderToolActions?.(part) : void 0
|
|
312
|
-
},
|
|
313
|
-
call.id
|
|
314
|
-
);
|
|
315
|
-
}) }) }, item.id);
|
|
316
|
-
}
|
|
317
|
-
if (item.kind === "status") {
|
|
318
|
-
return /* @__PURE__ */ jsx4(
|
|
319
|
-
AgentTimelineRow,
|
|
320
|
-
{
|
|
321
|
-
isLast,
|
|
322
|
-
accentClassName: TONE_STYLES[item.tone ?? "default"].dot,
|
|
323
|
-
children: /* @__PURE__ */ jsx4(StatusCard, { item })
|
|
324
|
-
},
|
|
325
|
-
item.id
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
if (item.kind === "artifact") {
|
|
280
|
+
const renderItem = (item) => {
|
|
281
|
+
if (item.kind === "message") {
|
|
282
|
+
return item.role === "user" ? /* @__PURE__ */ jsx4(UserMessage, { content: item.content, timestamp: item.timestamp }) : /* @__PURE__ */ jsx4(AssistantMessage, { item });
|
|
283
|
+
}
|
|
284
|
+
if (item.kind === "tool") {
|
|
285
|
+
return /* @__PURE__ */ jsx4(
|
|
286
|
+
ToolCallStep,
|
|
287
|
+
{
|
|
288
|
+
type: item.call.type,
|
|
289
|
+
label: item.call.label,
|
|
290
|
+
status: item.call.status,
|
|
291
|
+
detail: item.call.detail,
|
|
292
|
+
output: item.call.output,
|
|
293
|
+
duration: item.call.duration,
|
|
294
|
+
part: item.part,
|
|
295
|
+
actions: item.part ? renderToolActions?.(item.part) : void 0
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (item.kind === "tool_group") {
|
|
300
|
+
return /* @__PURE__ */ jsx4(ToolCallGroup, { title: item.title, children: item.calls.map((call, callIndex) => {
|
|
301
|
+
const part = item.parts?.[callIndex];
|
|
329
302
|
return /* @__PURE__ */ jsx4(
|
|
330
|
-
|
|
303
|
+
ToolCallStep,
|
|
331
304
|
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
305
|
+
type: call.type,
|
|
306
|
+
label: call.label,
|
|
307
|
+
status: call.status,
|
|
308
|
+
detail: call.detail,
|
|
309
|
+
output: call.output,
|
|
310
|
+
duration: call.duration,
|
|
311
|
+
part,
|
|
312
|
+
actions: part ? renderToolActions?.(part) : void 0
|
|
335
313
|
},
|
|
336
|
-
|
|
314
|
+
call.id
|
|
337
315
|
);
|
|
338
|
-
}
|
|
339
|
-
|
|
316
|
+
}) });
|
|
317
|
+
}
|
|
318
|
+
if (item.kind === "status") return /* @__PURE__ */ jsx4(StatusCard, { item });
|
|
319
|
+
if (item.kind === "artifact") return /* @__PURE__ */ jsx4(ArtifactCard, { item });
|
|
320
|
+
return item.content;
|
|
321
|
+
};
|
|
322
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("mx-auto flex w-full max-w-5xl flex-col px-4 py-4", className), children: [
|
|
323
|
+
renderList.map((item, index) => {
|
|
324
|
+
const kind = stepKind(item);
|
|
325
|
+
const prev = index > 0 ? stepKind(renderList[index - 1]) : void 0;
|
|
326
|
+
return /* @__PURE__ */ jsx4(
|
|
327
|
+
"div",
|
|
328
|
+
{
|
|
329
|
+
"data-timeline-step": kind,
|
|
330
|
+
className: cn(spacingBefore(prev, kind), kind === "tool" && ROW_BLEED),
|
|
331
|
+
children: renderItem(item)
|
|
332
|
+
},
|
|
333
|
+
item.id
|
|
334
|
+
);
|
|
340
335
|
}),
|
|
341
|
-
collapsible ? /* @__PURE__ */ jsx4(
|
|
336
|
+
collapsible ? /* @__PURE__ */ jsx4(
|
|
342
337
|
"button",
|
|
343
338
|
{
|
|
344
339
|
type: "button",
|
|
345
340
|
onClick: () => setExpanded((value) => !value),
|
|
346
|
-
className: "text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
|
|
341
|
+
className: "mt-2 self-start text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
|
|
347
342
|
children: collapsed ? `Show ${hiddenCount} more step${hiddenCount === 1 ? "" : "s"}` : "Show less"
|
|
348
343
|
}
|
|
349
|
-
)
|
|
344
|
+
) : null
|
|
350
345
|
] });
|
|
351
346
|
}
|
|
352
347
|
|
|
@@ -693,7 +688,7 @@ function ChatMessage({
|
|
|
693
688
|
children: [
|
|
694
689
|
!hideRoleLabel && /* @__PURE__ */ jsxs5("div", { className: cn("flex items-center gap-2 px-1", isUser && "flex-row-reverse"), children: [
|
|
695
690
|
/* @__PURE__ */ jsx6("span", { className: "font-medium text-foreground text-xs", children: isUser ? userLabel : assistantLabel }),
|
|
696
|
-
timestamp && /* @__PURE__ */ jsx6("span", { className: "text-muted-foreground text-xs", children:
|
|
691
|
+
timestamp && /* @__PURE__ */ jsx6("span", { className: "text-muted-foreground text-xs", children: formatTime2(timestamp) })
|
|
697
692
|
] }),
|
|
698
693
|
/* @__PURE__ */ jsxs5(
|
|
699
694
|
"div",
|
|
@@ -716,7 +711,7 @@ function ChatMessage({
|
|
|
716
711
|
}
|
|
717
712
|
);
|
|
718
713
|
}
|
|
719
|
-
function
|
|
714
|
+
function formatTime2(date) {
|
|
720
715
|
return date.toLocaleTimeString(void 0, {
|
|
721
716
|
hour: "numeric",
|
|
722
717
|
minute: "2-digit"
|