@tangle-network/ui 5.1.0 → 6.0.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 +13 -0
- package/dist/chat.js +5 -6
- package/dist/{chunk-54SQQMMM.js → chunk-AZWDI2JG.js} +1 -1
- package/dist/chunk-EOGJX2TU.js +366 -0
- package/dist/chunk-LASW7CYH.js +473 -0
- package/dist/{chunk-U4YRT6MT.js → chunk-O6NUUCT2.js} +1 -1
- package/dist/{chunk-CJJMKDNN.js → chunk-PN3S2MTV.js} +1 -1
- package/dist/{chunk-FKDZOA4S.js → chunk-SJ6IL4HI.js} +4 -4
- package/dist/{chunk-BX6AQMUS.js → chunk-ULDNFLIM.js} +44 -1
- package/dist/hooks.js +7 -5
- package/dist/index.js +13 -15
- package/dist/run.d.ts +5 -1
- package/dist/run.js +7 -8
- package/dist/sdk-hooks.js +7 -5
- package/dist/utils.js +4 -6
- package/package.json +2 -2
- package/src/run/inline-tool-item.tsx +11 -3
- package/src/run/tool-call-step.tsx +48 -146
- package/dist/chunk-3O4XJCOE.js +0 -176
- package/dist/chunk-4CLN43XT.js +0 -45
- package/dist/chunk-TAWY3KOH.js +0 -735
package/dist/run.js
CHANGED
|
@@ -2,20 +2,19 @@ import "./chunk-LQS34IGP.js";
|
|
|
2
2
|
import {
|
|
3
3
|
ToolCallFeed,
|
|
4
4
|
parseToolEvent
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-O6NUUCT2.js";
|
|
6
6
|
import {
|
|
7
|
-
ExpandedToolDetail,
|
|
8
7
|
InlineThinkingItem,
|
|
9
|
-
InlineToolItem,
|
|
10
|
-
LiveDuration,
|
|
11
8
|
RunGroup
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LASW7CYH.js";
|
|
13
10
|
import {
|
|
11
|
+
ExpandedToolDetail,
|
|
12
|
+
InlineToolItem,
|
|
13
|
+
LiveDuration,
|
|
14
14
|
ToolCallGroup,
|
|
15
15
|
ToolCallStep
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-BX6AQMUS.js";
|
|
16
|
+
} from "./chunk-EOGJX2TU.js";
|
|
17
|
+
import "./chunk-ULDNFLIM.js";
|
|
19
18
|
import "./chunk-AAUNOHVL.js";
|
|
20
19
|
import "./chunk-52Y3FMFI.js";
|
|
21
20
|
import "./chunk-GYPQXTJU.js";
|
package/dist/sdk-hooks.js
CHANGED
|
@@ -5,16 +5,18 @@ import {
|
|
|
5
5
|
useSSEStream,
|
|
6
6
|
useSdkSession,
|
|
7
7
|
useToolCallStream
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PN3S2MTV.js";
|
|
9
9
|
import "./chunk-OEX7NZE3.js";
|
|
10
10
|
import {
|
|
11
11
|
useAutoScroll,
|
|
12
12
|
useRunCollapseState,
|
|
13
13
|
useRunGroups
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-AZWDI2JG.js";
|
|
15
|
+
import "./chunk-O6NUUCT2.js";
|
|
16
|
+
import "./chunk-EOGJX2TU.js";
|
|
17
|
+
import "./chunk-ULDNFLIM.js";
|
|
18
|
+
import "./chunk-AAUNOHVL.js";
|
|
19
|
+
import "./chunk-ZRVH3WCA.js";
|
|
18
20
|
import "./chunk-FJBTCTZM.js";
|
|
19
21
|
import "./chunk-WUQDUBJG.js";
|
|
20
22
|
import "./chunk-RQHJBTEU.js";
|
package/dist/utils.js
CHANGED
|
@@ -3,17 +3,15 @@ import {
|
|
|
3
3
|
timeAgo
|
|
4
4
|
} from "./chunk-XGKULLYE.js";
|
|
5
5
|
import {
|
|
6
|
+
TOOL_CATEGORY_ICONS,
|
|
6
7
|
formatBytes,
|
|
7
8
|
formatDuration,
|
|
8
9
|
formatUptime,
|
|
9
|
-
truncateText
|
|
10
|
-
} from "./chunk-4CLN43XT.js";
|
|
11
|
-
import {
|
|
12
|
-
TOOL_CATEGORY_ICONS,
|
|
13
10
|
getToolCategory,
|
|
14
11
|
getToolDisplayMetadata,
|
|
15
|
-
getToolErrorText
|
|
16
|
-
|
|
12
|
+
getToolErrorText,
|
|
13
|
+
truncateText
|
|
14
|
+
} from "./chunk-ULDNFLIM.js";
|
|
17
15
|
import {
|
|
18
16
|
cn
|
|
19
17
|
} from "./chunk-RQHJBTEU.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"react": "^18 || ^19",
|
|
133
133
|
"react-dom": "^18 || ^19",
|
|
134
134
|
"react-router": "^7",
|
|
135
|
-
"@tangle-network/brand": "^0.
|
|
135
|
+
"@tangle-network/brand": "^0.7.0"
|
|
136
136
|
},
|
|
137
137
|
"peerDependenciesMeta": {
|
|
138
138
|
"@nanostores/react": {
|
|
@@ -53,6 +53,10 @@ export interface InlineToolItemProps {
|
|
|
53
53
|
className?: string;
|
|
54
54
|
contentClassName?: string;
|
|
55
55
|
actions?: ReactNode;
|
|
56
|
+
/** Override the derived title (default: from `getToolDisplayMetadata`). */
|
|
57
|
+
title?: string;
|
|
58
|
+
/** Override the derived inline description. */
|
|
59
|
+
description?: string;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
/**
|
|
@@ -68,9 +72,13 @@ export const InlineToolItem = memo(
|
|
|
68
72
|
className,
|
|
69
73
|
contentClassName,
|
|
70
74
|
actions,
|
|
75
|
+
title: titleOverride,
|
|
76
|
+
description: descriptionOverride,
|
|
71
77
|
}: InlineToolItemProps) => {
|
|
72
78
|
const [open, setOpen] = useState(false);
|
|
73
79
|
const meta = getToolDisplayMetadata(part);
|
|
80
|
+
const title = titleOverride ?? meta.title;
|
|
81
|
+
const description = descriptionOverride ?? meta.description;
|
|
74
82
|
const { status } = part.state;
|
|
75
83
|
const errorText = getToolErrorText(part);
|
|
76
84
|
|
|
@@ -127,11 +135,11 @@ export const InlineToolItem = memo(
|
|
|
127
135
|
</div>
|
|
128
136
|
|
|
129
137
|
<span className="truncate text-xs font-medium text-foreground">
|
|
130
|
-
{
|
|
138
|
+
{title}
|
|
131
139
|
</span>
|
|
132
|
-
{
|
|
140
|
+
{description ? (
|
|
133
141
|
<span className="hidden truncate text-xs font-mono text-muted-foreground sm:inline">
|
|
134
|
-
{
|
|
142
|
+
{description}
|
|
135
143
|
</span>
|
|
136
144
|
) : null}
|
|
137
145
|
|
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ToolCallStep —
|
|
2
|
+
* ToolCallStep — a single agent tool invocation as a collapsible activity step.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Now a thin adapter over the canonical `InlineToolItem`: it maps the flat
|
|
5
|
+
* `ToolCallData`-style props (label / status / detail / output / duration) onto
|
|
6
|
+
* a `ToolPart` and delegates rendering, so the timeline feed (`AgentTimeline`,
|
|
7
|
+
* `ToolCallFeed`) and the run group share ONE row implementation and one look.
|
|
8
|
+
* The bespoke row markup is gone; only the prop adapter remains.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
Terminal,
|
|
11
|
-
FileText,
|
|
12
|
-
FileCode,
|
|
13
|
-
Search,
|
|
14
|
-
CheckCircle,
|
|
15
|
-
AlertCircle,
|
|
16
|
-
ChevronRight,
|
|
17
|
-
Loader2,
|
|
18
|
-
FolderOpen,
|
|
19
|
-
Download,
|
|
20
|
-
Pencil,
|
|
21
|
-
Eye,
|
|
22
|
-
} from "lucide-react";
|
|
23
|
-
import { cn } from "../lib/utils";
|
|
11
|
+
import { type ReactNode } from "react";
|
|
24
12
|
import { CodeBlock } from "../markdown/code-block";
|
|
13
|
+
import type { ToolPart, ToolStatus } from "../types/parts";
|
|
14
|
+
import { InlineToolItem } from "./inline-tool-item";
|
|
25
15
|
|
|
26
16
|
export type ToolCallType =
|
|
27
17
|
| "bash"
|
|
@@ -65,52 +55,19 @@ const EXT_LANGUAGE: Record<string, string> = {
|
|
|
65
55
|
go: "go",
|
|
66
56
|
sql: "sql",
|
|
67
57
|
xml: "xml",
|
|
68
|
-
}
|
|
58
|
+
};
|
|
69
59
|
|
|
70
60
|
function inferLanguage(detail?: string, language?: string): string | undefined {
|
|
71
|
-
if (language) return language
|
|
72
|
-
if (!detail) return undefined
|
|
73
|
-
const ext = detail.split(".").pop()?.toLowerCase()
|
|
74
|
-
return ext ? EXT_LANGUAGE[ext] : undefined
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function isFilePath(detail: string): boolean {
|
|
78
|
-
return /[/\\]/.test(detail) || /\.\w{1,6}$/.test(detail)
|
|
61
|
+
if (language) return language;
|
|
62
|
+
if (!detail) return undefined;
|
|
63
|
+
const ext = detail.split(".").pop()?.toLowerCase();
|
|
64
|
+
return ext ? EXT_LANGUAGE[ext] : undefined;
|
|
79
65
|
}
|
|
80
66
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<div className="flex items-center gap-1.5 rounded-[var(--radius-sm)] border border-border bg-background px-2.5 py-1.5 font-mono text-xs min-w-0">
|
|
87
|
-
<FileCode className="h-3.5 w-3.5 shrink-0 text-primary" />
|
|
88
|
-
{dir && (
|
|
89
|
-
<span className="truncate text-muted-foreground">{dir}</span>
|
|
90
|
-
)}
|
|
91
|
-
<span className="shrink-0 font-semibold text-foreground">{filename}</span>
|
|
92
|
-
</div>
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const ICONS: Record<ToolCallType, typeof Terminal> = {
|
|
97
|
-
bash: Terminal,
|
|
98
|
-
read: Eye,
|
|
99
|
-
write: FileText,
|
|
100
|
-
edit: Pencil,
|
|
101
|
-
glob: FolderOpen,
|
|
102
|
-
grep: Search,
|
|
103
|
-
list: FolderOpen,
|
|
104
|
-
download: Download,
|
|
105
|
-
inspect: Search,
|
|
106
|
-
audit: CheckCircle,
|
|
107
|
-
unknown: FileCode,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const STATUS_COLORS: Record<ToolCallStatus, string> = {
|
|
111
|
-
running: "text-primary",
|
|
112
|
-
success: "text-[var(--code-success)]",
|
|
113
|
-
error: "text-[var(--code-error)]",
|
|
67
|
+
const STATUS_MAP: Record<ToolCallStatus, ToolStatus> = {
|
|
68
|
+
running: "running",
|
|
69
|
+
success: "completed",
|
|
70
|
+
error: "error",
|
|
114
71
|
};
|
|
115
72
|
|
|
116
73
|
export function ToolCallStep({
|
|
@@ -123,93 +80,38 @@ export function ToolCallStep({
|
|
|
123
80
|
duration,
|
|
124
81
|
className,
|
|
125
82
|
}: ToolCallStepProps) {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
83
|
+
const part: ToolPart = {
|
|
84
|
+
type: "tool",
|
|
85
|
+
id: `${type}:${label}`,
|
|
86
|
+
tool: type,
|
|
87
|
+
state: {
|
|
88
|
+
status: STATUS_MAP[status],
|
|
89
|
+
input: detail ? { detail } : undefined,
|
|
90
|
+
output,
|
|
91
|
+
time: duration != null ? { start: 0, end: duration } : undefined,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
129
95
|
const lang = inferLanguage(detail, language);
|
|
130
96
|
|
|
131
97
|
return (
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
className={cn(
|
|
150
|
-
"flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)]",
|
|
151
|
-
status === "running" && "bg-[var(--accent-surface-soft)] text-primary",
|
|
152
|
-
status === "success" && "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
153
|
-
status === "error" && "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
|
|
154
|
-
)}
|
|
155
|
-
>
|
|
156
|
-
{status === "running" ? (
|
|
157
|
-
<Loader2 className="h-3 w-3 animate-spin shrink-0" />
|
|
158
|
-
) : (
|
|
159
|
-
<Icon className={cn("h-3 w-3 shrink-0", STATUS_COLORS[status])} />
|
|
160
|
-
)}
|
|
161
|
-
</div>
|
|
162
|
-
|
|
163
|
-
{/* Label */}
|
|
164
|
-
<span className="truncate flex-1 font-sans text-foreground">
|
|
165
|
-
{label}
|
|
166
|
-
</span>
|
|
167
|
-
|
|
168
|
-
{/* Duration — quiet, before the status glyph */}
|
|
169
|
-
{duration !== undefined && status !== "running" && (
|
|
170
|
-
<span className="shrink-0 text-[11px] tabular-nums text-muted-foreground">
|
|
171
|
-
{duration < 1000 ? `${duration}ms` : `${(duration / 1000).toFixed(1)}s`}
|
|
172
|
-
</span>
|
|
173
|
-
)}
|
|
174
|
-
|
|
175
|
-
{/* Quiet status glyph — the loud uppercase pill read as harsh; the colored
|
|
176
|
-
icon carries the same signal calmly (running spins in the left badge). */}
|
|
177
|
-
{status === "success" && (
|
|
178
|
-
<CheckCircle className="h-3.5 w-3.5 shrink-0 text-[var(--surface-success-text)]" />
|
|
179
|
-
)}
|
|
180
|
-
{status === "error" && (
|
|
181
|
-
<AlertCircle className="h-3.5 w-3.5 shrink-0 text-[var(--surface-danger-text)]" />
|
|
182
|
-
)}
|
|
183
|
-
|
|
184
|
-
{/* Expand chevron */}
|
|
185
|
-
{hasExpandable && (
|
|
186
|
-
<ChevronRight
|
|
187
|
-
className={cn(
|
|
188
|
-
"h-3 w-3 text-muted-foreground transition-transform shrink-0",
|
|
189
|
-
expanded && "rotate-90",
|
|
190
|
-
)}
|
|
191
|
-
/>
|
|
192
|
-
)}
|
|
193
|
-
</button>
|
|
194
|
-
|
|
195
|
-
{/* Expandable content */}
|
|
196
|
-
{expanded && (detail || output) && (
|
|
197
|
-
<div className="space-y-2 border-t border-[var(--border-subtle)] bg-muted/40 px-3 py-2.5">
|
|
198
|
-
{detail && (
|
|
199
|
-
isFilePath(detail)
|
|
200
|
-
? <FilePathChip path={detail} />
|
|
201
|
-
: <div className="text-xs font-mono text-muted-foreground">{detail}</div>
|
|
202
|
-
)}
|
|
203
|
-
{output && (
|
|
204
|
-
<CodeBlock
|
|
205
|
-
code={output}
|
|
206
|
-
language={lang}
|
|
207
|
-
className="max-h-72 overflow-auto text-xs"
|
|
208
|
-
/>
|
|
209
|
-
)}
|
|
210
|
-
</div>
|
|
211
|
-
)}
|
|
212
|
-
</div>
|
|
98
|
+
<InlineToolItem
|
|
99
|
+
part={part}
|
|
100
|
+
title={label}
|
|
101
|
+
description={detail}
|
|
102
|
+
className={className}
|
|
103
|
+
renderToolDetail={
|
|
104
|
+
output
|
|
105
|
+
? () => (
|
|
106
|
+
<CodeBlock
|
|
107
|
+
code={output}
|
|
108
|
+
language={lang}
|
|
109
|
+
className="max-h-72 overflow-auto text-xs"
|
|
110
|
+
/>
|
|
111
|
+
)
|
|
112
|
+
: () => null
|
|
113
|
+
}
|
|
114
|
+
/>
|
|
213
115
|
);
|
|
214
116
|
}
|
|
215
117
|
|
|
@@ -224,7 +126,7 @@ export interface ToolCallGroupProps {
|
|
|
224
126
|
|
|
225
127
|
export function ToolCallGroup({ title, children, className }: ToolCallGroupProps) {
|
|
226
128
|
return (
|
|
227
|
-
<div className={
|
|
129
|
+
<div className={["my-2 space-y-2", className].filter(Boolean).join(" ")}>
|
|
228
130
|
{title && (
|
|
229
131
|
<div className="mb-1 px-1 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
|
230
132
|
{title}
|
package/dist/chunk-3O4XJCOE.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CodeBlock
|
|
3
|
-
} from "./chunk-WUQDUBJG.js";
|
|
4
|
-
import {
|
|
5
|
-
cn
|
|
6
|
-
} from "./chunk-RQHJBTEU.js";
|
|
7
|
-
|
|
8
|
-
// src/run/tool-call-step.tsx
|
|
9
|
-
import { useState } from "react";
|
|
10
|
-
import {
|
|
11
|
-
Terminal,
|
|
12
|
-
FileText,
|
|
13
|
-
FileCode,
|
|
14
|
-
Search,
|
|
15
|
-
CheckCircle,
|
|
16
|
-
AlertCircle,
|
|
17
|
-
ChevronRight,
|
|
18
|
-
Loader2,
|
|
19
|
-
FolderOpen,
|
|
20
|
-
Download,
|
|
21
|
-
Pencil,
|
|
22
|
-
Eye
|
|
23
|
-
} from "lucide-react";
|
|
24
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
25
|
-
var EXT_LANGUAGE = {
|
|
26
|
-
ts: "typescript",
|
|
27
|
-
tsx: "typescript",
|
|
28
|
-
js: "javascript",
|
|
29
|
-
jsx: "javascript",
|
|
30
|
-
mjs: "javascript",
|
|
31
|
-
cjs: "javascript",
|
|
32
|
-
css: "css",
|
|
33
|
-
scss: "scss",
|
|
34
|
-
json: "json",
|
|
35
|
-
jsonc: "json",
|
|
36
|
-
md: "markdown",
|
|
37
|
-
mdx: "markdown",
|
|
38
|
-
py: "python",
|
|
39
|
-
sh: "bash",
|
|
40
|
-
bash: "bash",
|
|
41
|
-
zsh: "bash",
|
|
42
|
-
html: "html",
|
|
43
|
-
htm: "html",
|
|
44
|
-
yaml: "yaml",
|
|
45
|
-
yml: "yaml",
|
|
46
|
-
toml: "toml",
|
|
47
|
-
rs: "rust",
|
|
48
|
-
go: "go",
|
|
49
|
-
sql: "sql",
|
|
50
|
-
xml: "xml"
|
|
51
|
-
};
|
|
52
|
-
function inferLanguage(detail, language) {
|
|
53
|
-
if (language) return language;
|
|
54
|
-
if (!detail) return void 0;
|
|
55
|
-
const ext = detail.split(".").pop()?.toLowerCase();
|
|
56
|
-
return ext ? EXT_LANGUAGE[ext] : void 0;
|
|
57
|
-
}
|
|
58
|
-
function isFilePath(detail) {
|
|
59
|
-
return /[/\\]/.test(detail) || /\.\w{1,6}$/.test(detail);
|
|
60
|
-
}
|
|
61
|
-
function FilePathChip({ path }) {
|
|
62
|
-
const parts = path.replace(/\\/g, "/").split("/");
|
|
63
|
-
const filename = parts.pop() ?? path;
|
|
64
|
-
const dir = parts.length > 0 ? parts.join("/") + "/" : "";
|
|
65
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 rounded-[var(--radius-sm)] border border-border bg-background px-2.5 py-1.5 font-mono text-xs min-w-0", children: [
|
|
66
|
-
/* @__PURE__ */ jsx(FileCode, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
67
|
-
dir && /* @__PURE__ */ jsx("span", { className: "truncate text-muted-foreground", children: dir }),
|
|
68
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-semibold text-foreground", children: filename })
|
|
69
|
-
] });
|
|
70
|
-
}
|
|
71
|
-
var ICONS = {
|
|
72
|
-
bash: Terminal,
|
|
73
|
-
read: Eye,
|
|
74
|
-
write: FileText,
|
|
75
|
-
edit: Pencil,
|
|
76
|
-
glob: FolderOpen,
|
|
77
|
-
grep: Search,
|
|
78
|
-
list: FolderOpen,
|
|
79
|
-
download: Download,
|
|
80
|
-
inspect: Search,
|
|
81
|
-
audit: CheckCircle,
|
|
82
|
-
unknown: FileCode
|
|
83
|
-
};
|
|
84
|
-
var STATUS_COLORS = {
|
|
85
|
-
running: "text-primary",
|
|
86
|
-
success: "text-[var(--code-success)]",
|
|
87
|
-
error: "text-[var(--code-error)]"
|
|
88
|
-
};
|
|
89
|
-
function ToolCallStep({
|
|
90
|
-
type,
|
|
91
|
-
label,
|
|
92
|
-
status,
|
|
93
|
-
detail,
|
|
94
|
-
output,
|
|
95
|
-
language,
|
|
96
|
-
duration,
|
|
97
|
-
className
|
|
98
|
-
}) {
|
|
99
|
-
const [expanded, setExpanded] = useState(false);
|
|
100
|
-
const Icon = ICONS[type] || ICONS.unknown;
|
|
101
|
-
const hasExpandable = !!(detail || output);
|
|
102
|
-
const lang = inferLanguage(detail, language);
|
|
103
|
-
return /* @__PURE__ */ jsxs(
|
|
104
|
-
"div",
|
|
105
|
-
{
|
|
106
|
-
className: cn(
|
|
107
|
-
"group overflow-hidden rounded-[var(--radius-lg)] border bg-card/40 transition-colors",
|
|
108
|
-
"border-[var(--border-subtle)] hover:border-border",
|
|
109
|
-
status === "error" && "border-[var(--surface-danger-border)]/60",
|
|
110
|
-
className
|
|
111
|
-
),
|
|
112
|
-
children: [
|
|
113
|
-
/* @__PURE__ */ jsxs(
|
|
114
|
-
"button",
|
|
115
|
-
{
|
|
116
|
-
onClick: () => hasExpandable && setExpanded(!expanded),
|
|
117
|
-
disabled: !hasExpandable,
|
|
118
|
-
className: cn(
|
|
119
|
-
"flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm",
|
|
120
|
-
hasExpandable && "cursor-pointer"
|
|
121
|
-
),
|
|
122
|
-
children: [
|
|
123
|
-
/* @__PURE__ */ jsx(
|
|
124
|
-
"div",
|
|
125
|
-
{
|
|
126
|
-
className: cn(
|
|
127
|
-
"flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)]",
|
|
128
|
-
status === "running" && "bg-[var(--accent-surface-soft)] text-primary",
|
|
129
|
-
status === "success" && "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
130
|
-
status === "error" && "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]"
|
|
131
|
-
),
|
|
132
|
-
children: status === "running" ? /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin shrink-0" }) : /* @__PURE__ */ jsx(Icon, { className: cn("h-3 w-3 shrink-0", STATUS_COLORS[status]) })
|
|
133
|
-
}
|
|
134
|
-
),
|
|
135
|
-
/* @__PURE__ */ jsx("span", { className: "truncate flex-1 font-sans text-foreground", children: label }),
|
|
136
|
-
duration !== void 0 && status !== "running" && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground", children: duration < 1e3 ? `${duration}ms` : `${(duration / 1e3).toFixed(1)}s` }),
|
|
137
|
-
status === "success" && /* @__PURE__ */ jsx(CheckCircle, { className: "h-3.5 w-3.5 shrink-0 text-[var(--surface-success-text)]" }),
|
|
138
|
-
status === "error" && /* @__PURE__ */ jsx(AlertCircle, { className: "h-3.5 w-3.5 shrink-0 text-[var(--surface-danger-text)]" }),
|
|
139
|
-
hasExpandable && /* @__PURE__ */ jsx(
|
|
140
|
-
ChevronRight,
|
|
141
|
-
{
|
|
142
|
-
className: cn(
|
|
143
|
-
"h-3 w-3 text-muted-foreground transition-transform shrink-0",
|
|
144
|
-
expanded && "rotate-90"
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
)
|
|
148
|
-
]
|
|
149
|
-
}
|
|
150
|
-
),
|
|
151
|
-
expanded && (detail || output) && /* @__PURE__ */ jsxs("div", { className: "space-y-2 border-t border-[var(--border-subtle)] bg-muted/40 px-3 py-2.5", children: [
|
|
152
|
-
detail && (isFilePath(detail) ? /* @__PURE__ */ jsx(FilePathChip, { path: detail }) : /* @__PURE__ */ jsx("div", { className: "text-xs font-mono text-muted-foreground", children: detail })),
|
|
153
|
-
output && /* @__PURE__ */ jsx(
|
|
154
|
-
CodeBlock,
|
|
155
|
-
{
|
|
156
|
-
code: output,
|
|
157
|
-
language: lang,
|
|
158
|
-
className: "max-h-72 overflow-auto text-xs"
|
|
159
|
-
}
|
|
160
|
-
)
|
|
161
|
-
] })
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
function ToolCallGroup({ title, children, className }) {
|
|
167
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("my-2 space-y-2", className), children: [
|
|
168
|
-
title && /* @__PURE__ */ jsx("div", { className: "mb-1 px-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: title }),
|
|
169
|
-
children
|
|
170
|
-
] });
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export {
|
|
174
|
-
ToolCallStep,
|
|
175
|
-
ToolCallGroup
|
|
176
|
-
};
|
package/dist/chunk-4CLN43XT.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// src/utils/format.ts
|
|
2
|
-
function formatDuration(ms) {
|
|
3
|
-
if (ms < 1e3) return "<1s";
|
|
4
|
-
const seconds = Math.floor(ms / 1e3);
|
|
5
|
-
if (seconds < 60) return `${seconds}s`;
|
|
6
|
-
const minutes = Math.floor(seconds / 60);
|
|
7
|
-
const remaining = seconds % 60;
|
|
8
|
-
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
9
|
-
}
|
|
10
|
-
function truncateText(text, max) {
|
|
11
|
-
const cleaned = text.replace(/\s+/g, " ").trim();
|
|
12
|
-
if (cleaned.length <= max) return cleaned;
|
|
13
|
-
return cleaned.slice(0, max).trim() + "...";
|
|
14
|
-
}
|
|
15
|
-
function formatUptime(ms) {
|
|
16
|
-
if (!Number.isFinite(ms) || ms < 0) return "\u2014";
|
|
17
|
-
const totalSeconds = Math.floor(ms / 1e3);
|
|
18
|
-
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
19
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
20
|
-
const seconds = totalSeconds % 60;
|
|
21
|
-
if (minutes < 60) return `${minutes}m ${seconds}s`;
|
|
22
|
-
const hours = Math.floor(minutes / 60);
|
|
23
|
-
const remMinutes = minutes % 60;
|
|
24
|
-
if (hours < 24) return `${hours}h ${remMinutes}m`;
|
|
25
|
-
const days = Math.floor(hours / 24);
|
|
26
|
-
const remHours = hours % 24;
|
|
27
|
-
return `${days}d ${remHours}h`;
|
|
28
|
-
}
|
|
29
|
-
function formatBytes(bytes) {
|
|
30
|
-
if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
|
|
31
|
-
if (bytes < 1024) return `${Math.round(bytes)} B`;
|
|
32
|
-
const kb = bytes / 1024;
|
|
33
|
-
if (kb < 1024) return `${kb < 10 ? kb.toFixed(1) : Math.round(kb)} KB`;
|
|
34
|
-
const mb = kb / 1024;
|
|
35
|
-
if (mb < 1024) return `${mb < 10 ? mb.toFixed(1) : Math.round(mb)} MB`;
|
|
36
|
-
const gb = mb / 1024;
|
|
37
|
-
return `${gb < 10 ? gb.toFixed(2) : gb.toFixed(1)} GB`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
formatDuration,
|
|
42
|
-
truncateText,
|
|
43
|
-
formatUptime,
|
|
44
|
-
formatBytes
|
|
45
|
-
};
|