@nextclaw/agent-chat-ui 0.2.20 → 0.3.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/dist/index.d.ts +14 -2
- package/dist/index.js +89 -9
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { RefObject } from 'react';
|
|
2
|
+
import { ReactNode, RefObject } from 'react';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
type ChatTexts = {
|
|
@@ -166,9 +166,18 @@ type ChatFileOperationBlockViewModel = {
|
|
|
166
166
|
rawText?: string;
|
|
167
167
|
truncated?: boolean;
|
|
168
168
|
};
|
|
169
|
+
type ChatToolActionViewModel = {
|
|
170
|
+
kind: "open-session";
|
|
171
|
+
sessionId: string;
|
|
172
|
+
sessionKind: "child" | "session";
|
|
173
|
+
agentId?: string;
|
|
174
|
+
label?: string;
|
|
175
|
+
parentSessionId?: string;
|
|
176
|
+
};
|
|
169
177
|
type ChatToolPartViewModel = {
|
|
170
178
|
kind: "call" | "result";
|
|
171
179
|
toolName: string;
|
|
180
|
+
agentId?: string;
|
|
172
181
|
summary?: string;
|
|
173
182
|
inputLabel?: string;
|
|
174
183
|
input?: string;
|
|
@@ -180,6 +189,7 @@ type ChatToolPartViewModel = {
|
|
|
180
189
|
titleLabel: string;
|
|
181
190
|
outputLabel: string;
|
|
182
191
|
emptyLabel: string;
|
|
192
|
+
action?: ChatToolActionViewModel;
|
|
183
193
|
fileOperation?: {
|
|
184
194
|
blocks: ChatFileOperationBlockViewModel[];
|
|
185
195
|
};
|
|
@@ -246,6 +256,8 @@ type ChatMessageListProps = {
|
|
|
246
256
|
hasAssistantDraft: boolean;
|
|
247
257
|
texts: ChatMessageTexts;
|
|
248
258
|
className?: string;
|
|
259
|
+
onToolAction?: (action: ChatToolActionViewModel) => void;
|
|
260
|
+
renderToolAgent?: (agentId: string) => ReactNode;
|
|
249
261
|
};
|
|
250
262
|
|
|
251
263
|
type ChatInputBarHandle = {
|
|
@@ -320,4 +332,4 @@ declare function resolveChatComposerSlashTrigger(nodes: ChatComposerNode[], sele
|
|
|
320
332
|
end: number;
|
|
321
333
|
} | null;
|
|
322
334
|
|
|
323
|
-
export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatFileOperationBlockViewModel, type ChatFileOperationLineViewModel, type ChatInlineContentSegmentViewModel, type ChatInlineHint, type ChatInlineTokenViewModel, ChatInputBar, type ChatInputBarActionsProps, type ChatInputBarHandle, type ChatInputBarProps, type ChatInputBarToolbarProps, ChatMessageList, type ChatMessageListProps, type ChatMessagePartViewModel, type ChatMessageRole, type ChatMessageTexts, type ChatMessageViewModel, type ChatSelectedItem, type ChatSkillPickerOption, type ChatSkillPickerProps, type ChatSlashItem, type ChatSlashMenuProps, type ChatTexts, type ChatToolPartViewModel, type ChatToolbarAccessory, type ChatToolbarAccessoryIcon, type ChatToolbarIcon, type ChatToolbarSelect, type ChatToolbarSelectGroup, type ChatToolbarSelectOption, copyText, createChatComposerNodesFromText, createChatComposerTextNode, createChatComposerTokenNode, createEmptyChatComposerNodes, extractChatComposerTokenKeys, normalizeChatComposerNodes, removeChatComposerTokenNodes, replaceChatComposerRange, resolveChatComposerSlashTrigger, serializeChatComposerDocument, serializeChatComposerPlainText, useActiveItemScroll, useCopyFeedback, useElementWidth, useStickyBottomScroll };
|
|
335
|
+
export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatFileOperationBlockViewModel, type ChatFileOperationLineViewModel, type ChatInlineContentSegmentViewModel, type ChatInlineHint, type ChatInlineTokenViewModel, ChatInputBar, type ChatInputBarActionsProps, type ChatInputBarHandle, type ChatInputBarProps, type ChatInputBarToolbarProps, ChatMessageList, type ChatMessageListProps, type ChatMessagePartViewModel, type ChatMessageRole, type ChatMessageTexts, type ChatMessageViewModel, type ChatSelectedItem, type ChatSkillPickerOption, type ChatSkillPickerProps, type ChatSlashItem, type ChatSlashMenuProps, type ChatTexts, type ChatToolActionViewModel, type ChatToolPartViewModel, type ChatToolbarAccessory, type ChatToolbarAccessoryIcon, type ChatToolbarIcon, type ChatToolbarSelect, type ChatToolbarSelectGroup, type ChatToolbarSelectOption, copyText, createChatComposerNodesFromText, createChatComposerTextNode, createChatComposerTokenNode, createEmptyChatComposerNodes, extractChatComposerTokenKeys, normalizeChatComposerNodes, removeChatComposerTokenNodes, replaceChatComposerRange, resolveChatComposerSlashTrigger, serializeChatComposerDocument, serializeChatComposerPlainText, useActiveItemScroll, useCopyFeedback, useElementWidth, useStickyBottomScroll };
|
package/dist/index.js
CHANGED
|
@@ -290,13 +290,20 @@ function ChatSlashMenu(props) {
|
|
|
290
290
|
] })
|
|
291
291
|
}
|
|
292
292
|
),
|
|
293
|
-
/* @__PURE__ */ jsx5("div", { className: "
|
|
293
|
+
/* @__PURE__ */ jsx5("div", { className: "min-w-0 p-2.5", children: activeItem ? /* @__PURE__ */ jsxs2("div", { className: "space-y-3", children: [
|
|
294
294
|
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
295
295
|
/* @__PURE__ */ jsx5("span", { className: "inline-flex rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-semibold text-primary", children: activeItem.subtitle }),
|
|
296
296
|
/* @__PURE__ */ jsx5("span", { className: "text-sm font-semibold text-gray-900", children: activeItem.title })
|
|
297
297
|
] }),
|
|
298
298
|
/* @__PURE__ */ jsx5("p", { className: "text-xs leading-5 text-gray-600", children: activeItem.description }),
|
|
299
|
-
/* @__PURE__ */ jsx5("div", { className: "space-y-1", children: activeItem.detailLines.map((line) => /* @__PURE__ */ jsx5(
|
|
299
|
+
/* @__PURE__ */ jsx5("div", { className: "space-y-1", children: activeItem.detailLines.map((line) => /* @__PURE__ */ jsx5(
|
|
300
|
+
"div",
|
|
301
|
+
{
|
|
302
|
+
className: "min-w-0 break-all rounded-md bg-gray-50 px-2 py-1 text-[11px] leading-5 text-gray-600",
|
|
303
|
+
children: line
|
|
304
|
+
},
|
|
305
|
+
line
|
|
306
|
+
)) }),
|
|
300
307
|
/* @__PURE__ */ jsx5("div", { className: "pt-1 text-[11px] text-gray-500", children: texts.slashSkillHintLabel })
|
|
301
308
|
] }) : /* @__PURE__ */ jsx5("div", { className: "text-xs text-gray-500", children: texts.slashHintLabel }) })
|
|
302
309
|
] })
|
|
@@ -2774,7 +2781,7 @@ function ToolCardContent({ children, className }) {
|
|
|
2774
2781
|
}
|
|
2775
2782
|
|
|
2776
2783
|
// src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx
|
|
2777
|
-
import { ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
|
|
2784
|
+
import { ArrowUpRight, ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
|
|
2778
2785
|
|
|
2779
2786
|
// src/components/chat/ui/chat-message-list/tool-card/tool-card-status.tsx
|
|
2780
2787
|
import { Check as Check4, Loader2, AlertTriangle, Minus } from "lucide-react";
|
|
@@ -2796,12 +2803,38 @@ function ToolStatusLabel({ card }) {
|
|
|
2796
2803
|
|
|
2797
2804
|
// src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx
|
|
2798
2805
|
import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2806
|
+
function ToolCardSessionActionButton({
|
|
2807
|
+
action,
|
|
2808
|
+
onAction
|
|
2809
|
+
}) {
|
|
2810
|
+
const isChildSession = action.sessionKind === "child";
|
|
2811
|
+
const label = isChildSession ? "Open child session" : "Open session";
|
|
2812
|
+
const handleClick = (event) => {
|
|
2813
|
+
event.stopPropagation();
|
|
2814
|
+
onAction(action);
|
|
2815
|
+
};
|
|
2816
|
+
return /* @__PURE__ */ jsx20(
|
|
2817
|
+
"button",
|
|
2818
|
+
{
|
|
2819
|
+
type: "button",
|
|
2820
|
+
onClick: handleClick,
|
|
2821
|
+
className: cn(
|
|
2822
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2 py-1 text-[10px] font-semibold uppercase tracking-[0.08em] transition-colors",
|
|
2823
|
+
"border-amber-200/80 bg-white/80 text-amber-800 hover:bg-amber-50"
|
|
2824
|
+
),
|
|
2825
|
+
"aria-label": label,
|
|
2826
|
+
title: label,
|
|
2827
|
+
children: /* @__PURE__ */ jsx20(ArrowUpRight, { className: "h-3 w-3", strokeWidth: 2.5 })
|
|
2828
|
+
}
|
|
2829
|
+
);
|
|
2830
|
+
}
|
|
2799
2831
|
function ToolCardHeader({
|
|
2800
2832
|
card,
|
|
2801
2833
|
icon: Icon2,
|
|
2802
2834
|
expanded,
|
|
2803
2835
|
canExpand,
|
|
2804
2836
|
hideSummary = false,
|
|
2837
|
+
actionSlot,
|
|
2805
2838
|
onToggle
|
|
2806
2839
|
}) {
|
|
2807
2840
|
const summaryPart = hideSummary ? "" : card.summary?.replace(/^(command|path|args|query|input):\s*/i, "") ?? "";
|
|
@@ -2825,6 +2858,7 @@ function ToolCardHeader({
|
|
|
2825
2858
|
] })
|
|
2826
2859
|
] }),
|
|
2827
2860
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3 shrink-0", children: [
|
|
2861
|
+
actionSlot,
|
|
2828
2862
|
/* @__PURE__ */ jsx20(ToolStatusLabel, { card }),
|
|
2829
2863
|
canExpand && (expanded ? /* @__PURE__ */ jsx20(ChevronDown2, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }) : /* @__PURE__ */ jsx20(ChevronRight, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }))
|
|
2830
2864
|
] })
|
|
@@ -2832,6 +2866,12 @@ function ToolCardHeader({
|
|
|
2832
2866
|
}
|
|
2833
2867
|
);
|
|
2834
2868
|
}
|
|
2869
|
+
function ToolCardHeaderSessionAction({
|
|
2870
|
+
action,
|
|
2871
|
+
onAction
|
|
2872
|
+
}) {
|
|
2873
|
+
return /* @__PURE__ */ jsx20(ToolCardSessionActionButton, { action, onAction });
|
|
2874
|
+
}
|
|
2835
2875
|
|
|
2836
2876
|
// src/components/chat/hooks/use-sticky-bottom-scroll.ts
|
|
2837
2877
|
import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef6 } from "react";
|
|
@@ -3497,7 +3537,11 @@ function SearchSnippetView({ card }) {
|
|
|
3497
3537
|
expanded && output && /* @__PURE__ */ jsx23(ToolCardContent, { children: /* @__PURE__ */ jsx23("pre", { className: "font-mono text-[12px] text-amber-950/70 whitespace-pre-wrap break-all w-full max-w-full max-h-64 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar-amber leading-relaxed", children: output }) })
|
|
3498
3538
|
] });
|
|
3499
3539
|
}
|
|
3500
|
-
function GenericToolCard({
|
|
3540
|
+
function GenericToolCard({
|
|
3541
|
+
card,
|
|
3542
|
+
onToolAction,
|
|
3543
|
+
renderToolAgent
|
|
3544
|
+
}) {
|
|
3501
3545
|
const input = card.input?.trim() ?? "";
|
|
3502
3546
|
const output = card.output?.trim() ?? "";
|
|
3503
3547
|
const isRunning = card.statusTone === "running";
|
|
@@ -3519,6 +3563,16 @@ function GenericToolCard({ card }) {
|
|
|
3519
3563
|
icon: Globe,
|
|
3520
3564
|
expanded,
|
|
3521
3565
|
canExpand: hasContent || isRunning,
|
|
3566
|
+
actionSlot: card.agentId || card.action && onToolAction ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3567
|
+
card.agentId && renderToolAgent ? renderToolAgent(card.agentId) : null,
|
|
3568
|
+
card.action && onToolAction ? /* @__PURE__ */ jsx23(
|
|
3569
|
+
ToolCardHeaderSessionAction,
|
|
3570
|
+
{
|
|
3571
|
+
action: card.action,
|
|
3572
|
+
onAction: onToolAction
|
|
3573
|
+
}
|
|
3574
|
+
) : null
|
|
3575
|
+
] }) : void 0,
|
|
3522
3576
|
onToggle
|
|
3523
3577
|
}
|
|
3524
3578
|
),
|
|
@@ -3551,7 +3605,11 @@ function isSearchTool(name) {
|
|
|
3551
3605
|
const lowered = name.toLowerCase();
|
|
3552
3606
|
return lowered === "grep_search" || lowered === "find_files" || lowered.includes("search");
|
|
3553
3607
|
}
|
|
3554
|
-
function ChatToolCard({
|
|
3608
|
+
function ChatToolCard({
|
|
3609
|
+
card,
|
|
3610
|
+
onToolAction,
|
|
3611
|
+
renderToolAgent
|
|
3612
|
+
}) {
|
|
3555
3613
|
if (isTerminalTool(card.toolName)) {
|
|
3556
3614
|
return /* @__PURE__ */ jsx24(TerminalExecutionView, { card });
|
|
3557
3615
|
}
|
|
@@ -3561,7 +3619,14 @@ function ChatToolCard({ card }) {
|
|
|
3561
3619
|
if (isSearchTool(card.toolName)) {
|
|
3562
3620
|
return /* @__PURE__ */ jsx24(SearchSnippetView, { card });
|
|
3563
3621
|
}
|
|
3564
|
-
return /* @__PURE__ */ jsx24(
|
|
3622
|
+
return /* @__PURE__ */ jsx24(
|
|
3623
|
+
GenericToolCard,
|
|
3624
|
+
{
|
|
3625
|
+
card,
|
|
3626
|
+
onToolAction,
|
|
3627
|
+
renderToolAgent
|
|
3628
|
+
}
|
|
3629
|
+
);
|
|
3565
3630
|
}
|
|
3566
3631
|
|
|
3567
3632
|
// src/components/chat/ui/chat-message-list/chat-unknown-part.tsx
|
|
@@ -3580,7 +3645,7 @@ function ChatUnknownPart(props) {
|
|
|
3580
3645
|
// src/components/chat/ui/chat-message-list/chat-message.tsx
|
|
3581
3646
|
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
3582
3647
|
var ChatMessage = memo(function ChatMessage2(props) {
|
|
3583
|
-
const { message, texts } = props;
|
|
3648
|
+
const { message, texts, onToolAction, renderToolAgent } = props;
|
|
3584
3649
|
const { role } = message;
|
|
3585
3650
|
const isUser = role === "user";
|
|
3586
3651
|
const isMessageInProgress = message.status === "pending" || message.status === "streaming";
|
|
@@ -3628,7 +3693,14 @@ var ChatMessage = memo(function ChatMessage2(props) {
|
|
|
3628
3693
|
);
|
|
3629
3694
|
}
|
|
3630
3695
|
if (type === "tool-card") {
|
|
3631
|
-
return /* @__PURE__ */ jsx26("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx26(
|
|
3696
|
+
return /* @__PURE__ */ jsx26("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx26(
|
|
3697
|
+
ChatToolCard,
|
|
3698
|
+
{
|
|
3699
|
+
card: part.card,
|
|
3700
|
+
onToolAction,
|
|
3701
|
+
renderToolAgent
|
|
3702
|
+
}
|
|
3703
|
+
) }, `tool-${index}`);
|
|
3632
3704
|
}
|
|
3633
3705
|
if (type === "file") {
|
|
3634
3706
|
return /* @__PURE__ */ jsx26(
|
|
@@ -3743,7 +3815,15 @@ function ChatMessageList(props) {
|
|
|
3743
3815
|
return /* @__PURE__ */ jsxs18("div", { className: cn("flex gap-3", isUser ? "justify-end" : "justify-start"), children: [
|
|
3744
3816
|
!isUser ? /* @__PURE__ */ jsx28(ChatMessageAvatar, { role: message.role }) : null,
|
|
3745
3817
|
/* @__PURE__ */ jsxs18("div", { className: cn("w-fit max-w-[92%] space-y-2", isUser && "flex flex-col items-end"), children: [
|
|
3746
|
-
/* @__PURE__ */ jsx28(
|
|
3818
|
+
/* @__PURE__ */ jsx28(
|
|
3819
|
+
ChatMessage,
|
|
3820
|
+
{
|
|
3821
|
+
message,
|
|
3822
|
+
texts: props.texts,
|
|
3823
|
+
onToolAction: props.onToolAction,
|
|
3824
|
+
renderToolAgent: props.renderToolAgent
|
|
3825
|
+
}
|
|
3826
|
+
),
|
|
3747
3827
|
/* @__PURE__ */ jsx28("div", { className: cn("flex items-center gap-2", isUser && "justify-end"), children: isGenerating ? /* @__PURE__ */ jsx28(ChatMessageTypingFooter, {}) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
3748
3828
|
/* @__PURE__ */ jsx28(ChatMessageMeta, { roleLabel: message.roleLabel, timestampLabel: message.timestampLabel, isUser }),
|
|
3749
3829
|
!isUser ? /* @__PURE__ */ jsx28(ChatMessageActionCopy, { message, texts: props.texts }) : null
|