@tangle-network/ui 7.0.0 → 8.1.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/dist/chat.d.ts +17 -72
- package/dist/chat.js +2 -4
- package/dist/{chunk-QIRVZMQY.js → chunk-C3BIVG72.js} +143 -107
- package/dist/{chunk-5CS3I7Y3.js → chunk-QUAU6ZNC.js} +111 -395
- package/dist/hooks.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -9
- package/dist/run.d.ts +30 -2
- package/dist/run.js +4 -6
- package/dist/sdk-hooks.d.ts +1 -1
- package/dist/{tool-call-feed-Bs3MyQMT.d.ts → tool-call-feed-D9iofJgW.d.ts} +1 -23
- package/package.json +2 -2
- package/src/chat/agent-timeline.tsx +139 -45
- package/src/chat/chat-container.tsx +6 -48
- package/src/chat/chat-message.tsx +0 -4
- package/src/chat/index.ts +0 -1
- package/src/markdown/markdown.stories.tsx +1 -1
- package/src/run/assistant-run-shell.tsx +115 -0
- package/src/run/index.ts +5 -1
- package/src/run/run-group.tsx +12 -76
- package/src/run/tool-call-step.tsx +5 -7
- package/src/chat/chat-input.stories.tsx +0 -142
- package/src/chat/chat-input.tsx +0 -389
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 8.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 79b55f5: Converge the two transcripts on one collapsible run. New `AssistantRunShell` primitive (the header · summary · status pill · chevron · Radix collapse extracted from `RunGroup`) is now used by both `RunGroup` and `AgentTimeline`, so there is one implementation of "an assistant run" instead of two divergent ones. `AgentTimeline` folds consecutive tool / tool-group items into that shell (`collapsibleToolRuns`, default on; `defaultToolRunsOpen`, default open) so a burst of tool activity reads as one toggleable step on the timeline spine instead of a long ladder of rows — matching `RunGroup`. Additive: `AgentTimeline`'s `items[]` API is unchanged and folding happens internally; consumers building their own item arrays keep working.
|
|
8
|
+
|
|
9
|
+
## 8.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 831e935: One composer, no zombie API. `ChatInput` is deleted — the canonical composer is `AgentComposer` in `@tangle-network/sandbox-ui`, composed below the transcript by the app. `ChatContainer` is now transcript-only: the input props (`onSend`, `onCancel`, `placeholder`, `hideInput`, `modelLabel`, `onModelClick`, `pendingFiles`, `onRemoveFile`, `onAttach`, `disabled`) and the `PendingFile` type are removed. `ChatMessage` drops the no-op `avatar`/`hideAvatar` props. `ToolCallStep`/`ToolCallGroup` are no longer exported (internal adapters over `InlineToolItem`); the `ToolCallType`/`ToolCallStatus` types stay public via `ToolCallData`, and `ToolCallFeed` is unchanged.
|
|
14
|
+
|
|
3
15
|
## 7.0.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/chat.d.ts
CHANGED
|
@@ -7,83 +7,23 @@ import { AgentBranding } from './types.js';
|
|
|
7
7
|
import { C as CustomToolRenderer } from './tool-display-z4JcDmMQ.js';
|
|
8
8
|
import { R as Run, G as GroupedMessage } from './run-PfLmDAox.js';
|
|
9
9
|
import { OpenUIAction } from './openui.js';
|
|
10
|
-
import { T as ToolCallData } from './tool-call-feed-
|
|
10
|
+
import { T as ToolCallData } from './tool-call-feed-D9iofJgW.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* - Enter to send, Shift+Enter for newline
|
|
17
|
-
* - Drag-and-drop files onto the input with styled overlay
|
|
18
|
-
* - File attachment button (files) + folder attachment button
|
|
19
|
-
* - Pending file/folder chips
|
|
20
|
-
* - Cancel button when streaming
|
|
21
|
-
* - Optional model selector pill
|
|
13
|
+
* Transcript-only container: message list + auto-scroll. Composers are
|
|
14
|
+
* composed BELOW this by the app (the canonical one is `AgentComposer` in
|
|
15
|
+
* `@tangle-network/sandbox-ui`) — this component never renders an input.
|
|
22
16
|
*/
|
|
23
|
-
interface PendingFile {
|
|
24
|
-
id: string;
|
|
25
|
-
name: string;
|
|
26
|
-
size: number;
|
|
27
|
-
type: "file" | "folder";
|
|
28
|
-
/** Number of files inside (for folders) */
|
|
29
|
-
fileCount?: number;
|
|
30
|
-
status: "pending" | "uploading" | "ready" | "error";
|
|
31
|
-
}
|
|
32
|
-
interface ChatInputProps {
|
|
33
|
-
onSend: (message: string, files?: File[]) => void;
|
|
34
|
-
onCancel?: () => void;
|
|
35
|
-
isStreaming?: boolean;
|
|
36
|
-
disabled?: boolean;
|
|
37
|
-
placeholder?: string;
|
|
38
|
-
/** Currently selected model label */
|
|
39
|
-
modelLabel?: string;
|
|
40
|
-
onModelClick?: () => void;
|
|
41
|
-
/** Pending uploaded files */
|
|
42
|
-
pendingFiles?: PendingFile[];
|
|
43
|
-
onRemoveFile?: (id: string) => void;
|
|
44
|
-
/** Called when files are attached (via button or drag-and-drop) */
|
|
45
|
-
onAttach?: (files: FileList) => void;
|
|
46
|
-
/** Called when a folder is selected via the folder button */
|
|
47
|
-
onAttachFolder?: (files: FileList) => void;
|
|
48
|
-
/** Accepted file types for the file input (e.g. ".pdf,.csv") */
|
|
49
|
-
accept?: string;
|
|
50
|
-
/** Drop zone overlay title */
|
|
51
|
-
dropTitle?: string;
|
|
52
|
-
/** Drop zone overlay description */
|
|
53
|
-
dropDescription?: string;
|
|
54
|
-
className?: string;
|
|
55
|
-
/** Label above the input. Set to null to hide. Default: "Agent Command Deck" */
|
|
56
|
-
inputLabel?: string | null;
|
|
57
|
-
/** Status text shown when idle. Set to null to hide. Default: "Ready for next instruction" */
|
|
58
|
-
idleStatus?: string | null;
|
|
59
|
-
/** Status text shown when streaming. Set to null to hide. Default: "Streaming response" */
|
|
60
|
-
streamingStatus?: string | null;
|
|
61
|
-
/** Hide the Cmd+L focus shortcut hint */
|
|
62
|
-
hideShortcutHint?: boolean;
|
|
63
|
-
}
|
|
64
|
-
declare function ChatInput({ onSend, onCancel, isStreaming, disabled, placeholder, modelLabel, onModelClick, pendingFiles, onRemoveFile, onAttach, onAttachFolder, accept, dropTitle, dropDescription, className, inputLabel, idleStatus, streamingStatus, hideShortcutHint, }: ChatInputProps): react_jsx_runtime.JSX.Element;
|
|
65
|
-
|
|
66
17
|
interface ChatContainerProps {
|
|
67
18
|
messages: SessionMessage[];
|
|
68
19
|
partMap: Record<string, SessionPart[]>;
|
|
69
20
|
isStreaming: boolean;
|
|
70
|
-
onSend?: (text: string) => void;
|
|
71
|
-
onCancel?: () => void;
|
|
72
21
|
branding?: AgentBranding;
|
|
73
|
-
placeholder?: string;
|
|
74
22
|
className?: string;
|
|
75
|
-
/** Hide the input area (useful for read-only views). */
|
|
76
|
-
hideInput?: boolean;
|
|
77
23
|
/** Custom renderer for tool details. Return ReactNode to override, null to use default. */
|
|
78
24
|
renderToolDetail?: CustomToolRenderer;
|
|
79
25
|
/** Presentation mode for the session view. */
|
|
80
26
|
presentation?: "runs" | "timeline";
|
|
81
|
-
modelLabel?: string;
|
|
82
|
-
onModelClick?: () => void;
|
|
83
|
-
pendingFiles?: PendingFile[];
|
|
84
|
-
onRemoveFile?: (id: string) => void;
|
|
85
|
-
onAttach?: (files: FileList) => void;
|
|
86
|
-
disabled?: boolean;
|
|
87
27
|
/** Callback when an OpenUI action button is pressed within inline OpenUI blocks. */
|
|
88
28
|
onOpenUIAction?: (action: OpenUIAction) => void;
|
|
89
29
|
/** Enable rendering OpenUI schemas inline in the chat timeline. Defaults to true. */
|
|
@@ -100,10 +40,10 @@ interface ChatContainerProps {
|
|
|
100
40
|
}) => ReactNode;
|
|
101
41
|
}
|
|
102
42
|
/**
|
|
103
|
-
*
|
|
43
|
+
* Chat transcript container: message list + auto-scroll.
|
|
104
44
|
* Orchestrates useRunGroups, useRunCollapseState, and useAutoScroll.
|
|
105
45
|
*/
|
|
106
|
-
declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming,
|
|
46
|
+
declare const ChatContainer: React.MemoExoticComponent<({ messages, partMap, isStreaming, branding, className, renderToolDetail, presentation, onOpenUIAction, enableOpenUI, renderRunActions, renderUserMessageActions, renderToolActions, }: ChatContainerProps) => react_jsx_runtime.JSX.Element>;
|
|
107
47
|
|
|
108
48
|
interface MessageListProps {
|
|
109
49
|
groups: GroupedMessage[];
|
|
@@ -158,10 +98,6 @@ interface ChatMessageProps {
|
|
|
158
98
|
assistantLabel?: string;
|
|
159
99
|
/** Hide the role label row entirely */
|
|
160
100
|
hideRoleLabel?: boolean;
|
|
161
|
-
/** @deprecated Avatars were removed from the bubble design; this prop is ignored. */
|
|
162
|
-
hideAvatar?: boolean;
|
|
163
|
-
/** @deprecated Avatars were removed from the bubble design; this prop is ignored. */
|
|
164
|
-
avatar?: ReactNode;
|
|
165
101
|
}
|
|
166
102
|
declare function ChatMessage({ role, content, toolCalls, isStreaming, timestamp, className, userLabel, assistantLabel, hideRoleLabel, }: ChatMessageProps): react_jsx_runtime.JSX.Element;
|
|
167
103
|
|
|
@@ -221,12 +157,21 @@ interface AgentTimelineProps {
|
|
|
221
157
|
isThinking?: boolean;
|
|
222
158
|
emptyState?: ReactNode;
|
|
223
159
|
className?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Fold consecutive tool / tool-group items into one collapsible run shell
|
|
162
|
+
* (the same `AssistantRunShell` `RunGroup` uses), so a burst of tool activity
|
|
163
|
+
* reads as a single toggleable step instead of a long ladder of rows.
|
|
164
|
+
* Default true; pass false for the flat one-row-per-tool timeline.
|
|
165
|
+
*/
|
|
166
|
+
collapsibleToolRuns?: boolean;
|
|
167
|
+
/** Start collapsed tool runs open (true) or collapsed (false). Default open. */
|
|
168
|
+
defaultToolRunsOpen?: boolean;
|
|
224
169
|
}
|
|
225
170
|
/**
|
|
226
171
|
* AgentTimeline — unified mixed-content timeline for agent-backed sandbox
|
|
227
172
|
* sessions. Renders messages, tool steps, status cards, and artifact handoffs in
|
|
228
173
|
* a single execution narrative.
|
|
229
174
|
*/
|
|
230
|
-
declare function AgentTimeline({ items, isThinking, emptyState, className, }: AgentTimelineProps): react_jsx_runtime.JSX.Element | null;
|
|
175
|
+
declare function AgentTimeline({ items, isThinking, emptyState, className, collapsibleToolRuns, defaultToolRunsOpen, }: AgentTimelineProps): react_jsx_runtime.JSX.Element | null;
|
|
231
176
|
|
|
232
|
-
export { AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, ChatContainer, type ChatContainerProps,
|
|
177
|
+
export { AgentTimeline, type AgentTimelineArtifactItem, type AgentTimelineCustomItem, type AgentTimelineItem, type AgentTimelineMessageItem, type AgentTimelineProps, type AgentTimelineStatusItem, type AgentTimelineTone, type AgentTimelineToolGroupItem, type AgentTimelineToolItem, ChatContainer, type ChatContainerProps, ChatMessage, type ChatMessageProps, MessageList, type MessageListProps, type MessageRole, ThinkingIndicator, type ThinkingIndicatorProps, UserMessage, type UserMessageProps };
|
package/dist/chat.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentTimeline,
|
|
3
3
|
ChatContainer,
|
|
4
|
-
ChatInput,
|
|
5
4
|
ChatMessage,
|
|
6
5
|
MessageList,
|
|
7
6
|
ThinkingIndicator,
|
|
8
7
|
UserMessage
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QUAU6ZNC.js";
|
|
10
9
|
import "./chunk-AZWDI2JG.js";
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-C3BIVG72.js";
|
|
12
11
|
import "./chunk-RKQDBRTC.js";
|
|
13
12
|
import "./chunk-ULDNFLIM.js";
|
|
14
13
|
import "./chunk-AAUNOHVL.js";
|
|
@@ -22,7 +21,6 @@ import "./chunk-RQHJBTEU.js";
|
|
|
22
21
|
export {
|
|
23
22
|
AgentTimeline,
|
|
24
23
|
ChatContainer,
|
|
25
|
-
ChatInput,
|
|
26
24
|
ChatMessage,
|
|
27
25
|
MessageList,
|
|
28
26
|
ThinkingIndicator,
|
|
@@ -108,14 +108,68 @@ var InlineThinkingItem = memo(
|
|
|
108
108
|
);
|
|
109
109
|
InlineThinkingItem.displayName = "InlineThinkingItem";
|
|
110
110
|
|
|
111
|
+
// src/run/assistant-run-shell.tsx
|
|
112
|
+
import * as Collapsible2 from "@radix-ui/react-collapsible";
|
|
113
|
+
import { ChevronDown, ChevronRight as ChevronRight2, Loader2, Sparkles } from "lucide-react";
|
|
114
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
115
|
+
function AssistantRunShell({
|
|
116
|
+
label,
|
|
117
|
+
summary,
|
|
118
|
+
collapsedPreview,
|
|
119
|
+
badges,
|
|
120
|
+
isStreaming,
|
|
121
|
+
collapsed,
|
|
122
|
+
onToggle,
|
|
123
|
+
headerActions,
|
|
124
|
+
children,
|
|
125
|
+
className
|
|
126
|
+
}) {
|
|
127
|
+
return /* @__PURE__ */ jsx2(Collapsible2.Root, { open: !collapsed, onOpenChange: () => onToggle(), children: /* @__PURE__ */ jsxs2(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
className: cn(
|
|
131
|
+
"rounded-[28px] border border-[var(--border-subtle)] bg-[var(--bg-card)] shadow-none",
|
|
132
|
+
className
|
|
133
|
+
),
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-3 px-3 py-2.5", children: [
|
|
136
|
+
/* @__PURE__ */ jsx2(Collapsible2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx2(
|
|
137
|
+
"button",
|
|
138
|
+
{
|
|
139
|
+
type: "button",
|
|
140
|
+
className: "w-full rounded-[20px] bg-transparent px-0 py-0 text-left transition-colors hover:bg-transparent",
|
|
141
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
142
|
+
/* @__PURE__ */ jsx2("span", { className: "font-semibold text-foreground text-sm", children: label }),
|
|
143
|
+
summary ? /* @__PURE__ */ jsx2("span", { className: "text-[11px] text-muted-foreground", children: summary }) : null,
|
|
144
|
+
collapsed && collapsedPreview ? /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate text-[11px] text-foreground/70", children: collapsedPreview }) : null,
|
|
145
|
+
/* @__PURE__ */ jsxs2("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
146
|
+
badges,
|
|
147
|
+
isStreaming ? /* @__PURE__ */ jsxs2("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: [
|
|
148
|
+
/* @__PURE__ */ jsx2(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
|
|
149
|
+
"Running"
|
|
150
|
+
] }) : /* @__PURE__ */ jsxs2("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: [
|
|
151
|
+
/* @__PURE__ */ jsx2(Sparkles, { className: "h-2.5 w-2.5" }),
|
|
152
|
+
"Done"
|
|
153
|
+
] }),
|
|
154
|
+
collapsed ? /* @__PURE__ */ jsx2(ChevronRight2, { className: "h-3.5 w-3.5 text-muted-foreground" }) : /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
155
|
+
] })
|
|
156
|
+
] })
|
|
157
|
+
}
|
|
158
|
+
) }),
|
|
159
|
+
headerActions ? /* @__PURE__ */ jsx2("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-1.5 pt-1", children: headerActions }) : null
|
|
160
|
+
] }),
|
|
161
|
+
collapsed && collapsedPreview ? /* @__PURE__ */ jsx2("div", { className: "line-clamp-2 px-4 pb-4 text-sm leading-6 text-muted-foreground", children: collapsedPreview }) : null,
|
|
162
|
+
/* @__PURE__ */ jsx2(Collapsible2.Content, { className: "overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp", children: /* @__PURE__ */ jsx2("div", { className: "border-t border-[var(--border-subtle)] px-4 pb-4 pt-3", children }) })
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
) });
|
|
166
|
+
}
|
|
167
|
+
|
|
111
168
|
// src/run/run-group.tsx
|
|
112
169
|
import { memo as memo2, useMemo } from "react";
|
|
113
|
-
import * as Collapsible2 from "@radix-ui/react-collapsible";
|
|
114
170
|
import {
|
|
115
171
|
Bot,
|
|
116
|
-
Loader2,
|
|
117
|
-
ChevronDown,
|
|
118
|
-
ChevronRight as ChevronRight2,
|
|
172
|
+
Loader2 as Loader22,
|
|
119
173
|
Terminal,
|
|
120
174
|
FileEdit,
|
|
121
175
|
FileSearch,
|
|
@@ -123,10 +177,9 @@ import {
|
|
|
123
177
|
PencilLine,
|
|
124
178
|
Globe,
|
|
125
179
|
ClipboardList,
|
|
126
|
-
Settings
|
|
127
|
-
Sparkles
|
|
180
|
+
Settings
|
|
128
181
|
} from "lucide-react";
|
|
129
|
-
import { jsx as
|
|
182
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
130
183
|
var DEFAULT_BRANDING = {
|
|
131
184
|
label: "Agent",
|
|
132
185
|
accentClass: "text-primary",
|
|
@@ -142,15 +195,15 @@ function AssistantShell({
|
|
|
142
195
|
isStreaming,
|
|
143
196
|
children
|
|
144
197
|
}) {
|
|
145
|
-
return /* @__PURE__ */
|
|
146
|
-
/* @__PURE__ */
|
|
147
|
-
/* @__PURE__ */
|
|
148
|
-
isStreaming ? /* @__PURE__ */
|
|
149
|
-
/* @__PURE__ */
|
|
198
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
|
|
199
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs", children: [
|
|
200
|
+
/* @__PURE__ */ jsx3("span", { children: branding.label }),
|
|
201
|
+
isStreaming ? /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
202
|
+
/* @__PURE__ */ jsx3(Loader22, { className: "h-3 w-3 animate-spin" }),
|
|
150
203
|
"Thinking"
|
|
151
204
|
] }) : null
|
|
152
205
|
] }),
|
|
153
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ jsx3("div", { className: ASSISTANT_SHELL, children })
|
|
154
207
|
] });
|
|
155
208
|
}
|
|
156
209
|
var CATEGORY_ICON_MAP = {
|
|
@@ -242,14 +295,14 @@ function CategoryBadges({ categories }) {
|
|
|
242
295
|
[categories]
|
|
243
296
|
);
|
|
244
297
|
if (sorted.length === 0) return null;
|
|
245
|
-
return /* @__PURE__ */
|
|
298
|
+
return /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-1", children: sorted.map((cat) => {
|
|
246
299
|
const Icon = CATEGORY_ICON_MAP[cat] ?? Settings;
|
|
247
|
-
return /* @__PURE__ */
|
|
300
|
+
return /* @__PURE__ */ jsx3(
|
|
248
301
|
"span",
|
|
249
302
|
{
|
|
250
303
|
title: cat,
|
|
251
304
|
className: "flex h-5 w-5 items-center justify-center rounded border border-border text-muted-foreground",
|
|
252
|
-
children: /* @__PURE__ */
|
|
305
|
+
children: /* @__PURE__ */ jsx3(Icon, { className: "h-3 w-3" })
|
|
253
306
|
},
|
|
254
307
|
cat
|
|
255
308
|
);
|
|
@@ -310,10 +363,10 @@ var RunGroup = memo2(
|
|
|
310
363
|
if (!isStreaming) {
|
|
311
364
|
return null;
|
|
312
365
|
}
|
|
313
|
-
return /* @__PURE__ */
|
|
314
|
-
/* @__PURE__ */
|
|
315
|
-
/* @__PURE__ */
|
|
316
|
-
/* @__PURE__ */
|
|
366
|
+
return /* @__PURE__ */ jsx3(AssistantShell, { branding, isStreaming: true, children: /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-2 px-0.5 py-0.5 text-sm text-[var(--text-muted)]", children: /* @__PURE__ */ jsxs3("span", { className: "flex gap-[5px]", children: [
|
|
367
|
+
/* @__PURE__ */ jsx3("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "0ms" } }),
|
|
368
|
+
/* @__PURE__ */ jsx3("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "150ms" } }),
|
|
369
|
+
/* @__PURE__ */ jsx3("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "300ms" } })
|
|
317
370
|
] }) }) });
|
|
318
371
|
}
|
|
319
372
|
const showTraceChrome = allParts.some(({ part }) => {
|
|
@@ -326,32 +379,32 @@ var RunGroup = memo2(
|
|
|
326
379
|
return false;
|
|
327
380
|
});
|
|
328
381
|
if (!showTraceChrome) {
|
|
329
|
-
return /* @__PURE__ */
|
|
382
|
+
return /* @__PURE__ */ jsx3(AssistantShell, { branding, isStreaming, children: allParts.map(({ part, msgId, index }) => {
|
|
330
383
|
const key = `${msgId}-${index}`;
|
|
331
384
|
if (part.type === "tool" && isOpenUITool(part)) {
|
|
332
385
|
const toolPart = part;
|
|
333
386
|
const schema = extractOpenUISchema(toolPart.state.output);
|
|
334
387
|
const summary = getOpenUISummary(toolPart.state.output);
|
|
335
388
|
if (toolPart.state.status === "completed" && schema) {
|
|
336
|
-
return /* @__PURE__ */
|
|
389
|
+
return /* @__PURE__ */ jsxs3(
|
|
337
390
|
"div",
|
|
338
391
|
{
|
|
339
392
|
className: "overflow-hidden rounded-[22px] border border-[var(--border-subtle)] bg-[var(--bg-root)]",
|
|
340
393
|
children: [
|
|
341
|
-
summary ? /* @__PURE__ */
|
|
342
|
-
/* @__PURE__ */
|
|
394
|
+
summary ? /* @__PURE__ */ jsx3("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3 text-sm leading-6 text-foreground", children: summary }) : null,
|
|
395
|
+
/* @__PURE__ */ jsx3("div", { className: "p-4", children: /* @__PURE__ */ jsx3(OpenUIArtifactRenderer, { schema }) })
|
|
343
396
|
]
|
|
344
397
|
},
|
|
345
398
|
key
|
|
346
399
|
);
|
|
347
400
|
}
|
|
348
401
|
if (toolPart.state.status === "running") {
|
|
349
|
-
return /* @__PURE__ */
|
|
402
|
+
return /* @__PURE__ */ jsxs3(
|
|
350
403
|
"div",
|
|
351
404
|
{
|
|
352
405
|
className: "flex items-center gap-2 rounded-[18px] border border-[var(--border-subtle)] bg-[var(--bg-root)] px-4 py-3 text-sm text-muted-foreground",
|
|
353
406
|
children: [
|
|
354
|
-
/* @__PURE__ */
|
|
407
|
+
/* @__PURE__ */ jsx3(Loader22, { className: "h-4 w-4 animate-spin text-primary" }),
|
|
355
408
|
"Building view\u2026"
|
|
356
409
|
]
|
|
357
410
|
},
|
|
@@ -360,102 +413,85 @@ var RunGroup = memo2(
|
|
|
360
413
|
}
|
|
361
414
|
}
|
|
362
415
|
if (part.type === "text" && !part.synthetic && part.text.trim()) {
|
|
363
|
-
return /* @__PURE__ */
|
|
416
|
+
return /* @__PURE__ */ jsx3("div", { className: "px-0.5", children: /* @__PURE__ */ jsx3(Markdown, { className: "tangle-prose text-[15px] leading-7 text-[var(--text-primary)]", children: part.text }) }, key);
|
|
364
417
|
}
|
|
365
418
|
return null;
|
|
366
419
|
}) });
|
|
367
420
|
}
|
|
368
|
-
return /* @__PURE__ */
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if (part.type === "tool") {
|
|
405
|
-
if (isOpenUITool(part)) {
|
|
406
|
-
const toolPart = part;
|
|
407
|
-
const schema = extractOpenUISchema(toolPart.state.output);
|
|
408
|
-
const summary = getOpenUISummary(toolPart.state.output);
|
|
409
|
-
if (toolPart.state.status === "completed" && schema) {
|
|
410
|
-
node = /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-[24px] border border-[var(--border-subtle)] bg-[var(--bg-card)]", children: [
|
|
411
|
-
summary ? /* @__PURE__ */ jsxs2("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3", children: [
|
|
412
|
-
/* @__PURE__ */ jsx2("div", { className: "text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "View" }),
|
|
413
|
-
/* @__PURE__ */ jsx2("div", { className: "mt-1 text-sm leading-6 text-foreground", children: summary })
|
|
414
|
-
] }) : null,
|
|
415
|
-
/* @__PURE__ */ jsx2("div", { className: "p-4", children: /* @__PURE__ */ jsx2(OpenUIArtifactRenderer, { schema }) })
|
|
416
|
-
] });
|
|
417
|
-
} else if (toolPart.state.status === "running") {
|
|
418
|
-
node = /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 rounded-[20px] border border-[var(--border-subtle)] bg-[var(--bg-card)] px-4 py-3 text-sm text-muted-foreground", children: [
|
|
419
|
-
/* @__PURE__ */ jsx2(Loader2, { className: "h-4 w-4 animate-spin text-primary" }),
|
|
420
|
-
"Building view\u2026"
|
|
421
|
-
] });
|
|
421
|
+
return /* @__PURE__ */ jsx3(
|
|
422
|
+
AssistantRunShell,
|
|
423
|
+
{
|
|
424
|
+
label: branding.label,
|
|
425
|
+
summary: renderSummary(run) || void 0,
|
|
426
|
+
collapsedPreview: run.summaryText ?? void 0,
|
|
427
|
+
badges: /* @__PURE__ */ jsx3(CategoryBadges, { categories: stats.toolCategories }),
|
|
428
|
+
isStreaming,
|
|
429
|
+
collapsed,
|
|
430
|
+
onToggle,
|
|
431
|
+
headerActions,
|
|
432
|
+
children: allParts.map(({ part, msgId, index }, partIndex) => {
|
|
433
|
+
const key = `${msgId}-${index}`;
|
|
434
|
+
const prev = allParts[partIndex - 1]?.part;
|
|
435
|
+
const connectedTool = part.type === "tool" && prev?.type === "tool" && !isOpenUITool(part) && !isOpenUITool(prev);
|
|
436
|
+
const gapClass = partIndex === 0 ? "" : connectedTool ? "mt-px" : "mt-3";
|
|
437
|
+
let node = null;
|
|
438
|
+
if (part.type === "tool") {
|
|
439
|
+
if (isOpenUITool(part)) {
|
|
440
|
+
const toolPart = part;
|
|
441
|
+
const schema = extractOpenUISchema(toolPart.state.output);
|
|
442
|
+
const summary = getOpenUISummary(toolPart.state.output);
|
|
443
|
+
if (toolPart.state.status === "completed" && schema) {
|
|
444
|
+
node = /* @__PURE__ */ jsxs3("div", { className: "overflow-hidden rounded-[24px] border border-[var(--border-subtle)] bg-[var(--bg-card)]", children: [
|
|
445
|
+
summary ? /* @__PURE__ */ jsxs3("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3", children: [
|
|
446
|
+
/* @__PURE__ */ jsx3("div", { className: "text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "View" }),
|
|
447
|
+
/* @__PURE__ */ jsx3("div", { className: "mt-1 text-sm leading-6 text-foreground", children: summary })
|
|
448
|
+
] }) : null,
|
|
449
|
+
/* @__PURE__ */ jsx3("div", { className: "p-4", children: /* @__PURE__ */ jsx3(OpenUIArtifactRenderer, { schema }) })
|
|
450
|
+
] });
|
|
451
|
+
} else if (toolPart.state.status === "running") {
|
|
452
|
+
node = /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3 rounded-[20px] border border-[var(--border-subtle)] bg-[var(--bg-card)] px-4 py-3 text-sm text-muted-foreground", children: [
|
|
453
|
+
/* @__PURE__ */ jsx3(Loader22, { className: "h-4 w-4 animate-spin text-primary" }),
|
|
454
|
+
"Building view\u2026"
|
|
455
|
+
] });
|
|
456
|
+
}
|
|
422
457
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
458
|
+
if (node === null) {
|
|
459
|
+
node = /* @__PURE__ */ jsx3(
|
|
460
|
+
InlineToolItem,
|
|
461
|
+
{
|
|
462
|
+
part,
|
|
463
|
+
renderToolDetail,
|
|
464
|
+
groupPosition: getToolGroupPosition(partIndex, allParts),
|
|
465
|
+
actions: renderToolActions?.(part, {
|
|
466
|
+
run,
|
|
467
|
+
messageId: msgId,
|
|
468
|
+
partIndex: index
|
|
469
|
+
})
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
} else if (part.type === "reasoning") {
|
|
474
|
+
node = /* @__PURE__ */ jsx3(
|
|
475
|
+
InlineThinkingItem,
|
|
427
476
|
{
|
|
428
477
|
part,
|
|
429
|
-
|
|
430
|
-
groupPosition: getToolGroupPosition(partIndex, allParts),
|
|
431
|
-
actions: renderToolActions?.(part, {
|
|
432
|
-
run,
|
|
433
|
-
messageId: msgId,
|
|
434
|
-
partIndex: index
|
|
435
|
-
})
|
|
478
|
+
defaultOpen: isStreaming
|
|
436
479
|
}
|
|
437
480
|
);
|
|
481
|
+
} else if (part.type === "text" && !part.synthetic && part.text.trim()) {
|
|
482
|
+
node = /* @__PURE__ */ jsx3("div", { className: "px-1 py-1", children: /* @__PURE__ */ jsx3(Markdown, { className: "tangle-prose text-[15px] leading-7", children: part.text }) });
|
|
438
483
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
defaultOpen: isStreaming
|
|
445
|
-
}
|
|
446
|
-
);
|
|
447
|
-
} else if (part.type === "text" && !part.synthetic && part.text.trim()) {
|
|
448
|
-
node = /* @__PURE__ */ jsx2("div", { className: "px-1 py-1", children: /* @__PURE__ */ jsx2(Markdown, { className: "tangle-prose text-[15px] leading-7", children: part.text }) });
|
|
449
|
-
}
|
|
450
|
-
if (!node) return null;
|
|
451
|
-
return /* @__PURE__ */ jsx2("div", { className: gapClass, children: node }, key);
|
|
452
|
-
}) }) })
|
|
453
|
-
] }) });
|
|
484
|
+
if (!node) return null;
|
|
485
|
+
return /* @__PURE__ */ jsx3("div", { className: gapClass, children: node }, key);
|
|
486
|
+
})
|
|
487
|
+
}
|
|
488
|
+
);
|
|
454
489
|
}
|
|
455
490
|
);
|
|
456
491
|
RunGroup.displayName = "RunGroup";
|
|
457
492
|
|
|
458
493
|
export {
|
|
459
494
|
InlineThinkingItem,
|
|
495
|
+
AssistantRunShell,
|
|
460
496
|
RunGroup
|
|
461
497
|
};
|