@blade-hq/agent-kit 0.4.6 → 0.4.7

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.
@@ -174,7 +174,13 @@ import {
174
174
  X as X2
175
175
  } from "lucide-react";
176
176
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
177
- import { useEffect as useEffect7, useEffectEvent as useEffectEvent2, useMemo as useMemo6, useRef as useRef4, useState as useState6 } from "react";
177
+ import {
178
+ useEffect as useEffect7,
179
+ useEffectEvent as useEffectEvent2,
180
+ useMemo as useMemo6,
181
+ useRef as useRef4,
182
+ useState as useState6
183
+ } from "react";
178
184
  import { createRoot } from "react-dom/client";
179
185
  import { toast } from "sonner";
180
186
 
@@ -1532,7 +1538,9 @@ function SkillStatusBar({
1532
1538
  sessionId,
1533
1539
  onResync,
1534
1540
  isResyncing = false,
1535
- vertical = false
1541
+ vertical = false,
1542
+ className,
1543
+ innerClassName
1536
1544
  }) {
1537
1545
  const { data: skillStats, error, loading } = useSkillStats(sessionId);
1538
1546
  const { data: sessionSkills = [] } = useQuery5({
@@ -1598,7 +1606,7 @@ function SkillStatusBar({
1598
1606
  const containerClass = vertical ? "text-[11px] text-[hsl(var(--muted-foreground))]" : "bg-[hsl(var(--background))] px-5 pt-2";
1599
1607
  const innerClass = vertical ? "" : "mx-auto max-w-3xl";
1600
1608
  const listClass = vertical ? "flex flex-col items-stretch gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]" : "flex flex-wrap items-center gap-2 text-[10px] text-[hsl(var(--muted-foreground))]";
1601
- return /* @__PURE__ */ jsx7("div", { className: containerClass, children: /* @__PURE__ */ jsx7("div", { className: innerClass, children: /* @__PURE__ */ jsxs6("div", { className: listClass, children: [
1609
+ return /* @__PURE__ */ jsx7("div", { className: cn(containerClass, className), children: /* @__PURE__ */ jsx7("div", { className: cn(innerClass, innerClassName), children: /* @__PURE__ */ jsxs6("div", { className: listClass, children: [
1602
1610
  tokenSummary ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1", children: [
1603
1611
  /* @__PURE__ */ jsx7(
1604
1612
  ProgressCircle,
@@ -2384,6 +2392,11 @@ function ChatInput({
2384
2392
  externalDraft,
2385
2393
  externalAttachments,
2386
2394
  maxWidthClassName = "max-w-3xl",
2395
+ className,
2396
+ innerClassName,
2397
+ SkillStatusBarComponent = SkillStatusBar,
2398
+ skillStatusBarClassName,
2399
+ skillStatusBarInnerClassName,
2387
2400
  onResyncSkills,
2388
2401
  isResyncingSkills = false
2389
2402
  }) {
@@ -3019,7 +3032,7 @@ function ChatInput({
3019
3032
  const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
3020
3033
  const isSendDisabled = connectionStatus !== "connected" || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
3021
3034
  return /* @__PURE__ */ jsxs7(Fragment, { children: [
3022
- /* @__PURE__ */ jsx8("div", { className: "bg-[hsl(var(--background))] px-5 py-3", children: /* @__PURE__ */ jsx8("div", { className: `mx-auto ${maxWidthClassName}`, children: /* @__PURE__ */ jsx8(
3035
+ /* @__PURE__ */ jsx8("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsx8("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: /* @__PURE__ */ jsx8(
3023
3036
  "div",
3024
3037
  {
3025
3038
  className: "relative",
@@ -3321,12 +3334,14 @@ function ChatInput({
3321
3334
  ),
3322
3335
  /* @__PURE__ */ jsx8("div", { className: "pointer-events-auto absolute bottom-full right-0 z-30 hidden pb-2 group-hover/help:block group-focus-within/help:block", children: /* @__PURE__ */ jsxs7("div", { className: "min-w-64 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-left text-[11px] leading-5 text-[hsl(var(--popover-foreground))] shadow-lg", children: [
3323
3336
  activeSessionId ? /* @__PURE__ */ jsx8("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: /* @__PURE__ */ jsx8(
3324
- SkillStatusBar,
3337
+ SkillStatusBarComponent,
3325
3338
  {
3326
3339
  sessionId: activeSessionId,
3327
3340
  onResync: onResyncSkills,
3328
3341
  isResyncing: isResyncingSkills,
3329
- vertical: true
3342
+ vertical: true,
3343
+ className: skillStatusBarClassName,
3344
+ innerClassName: skillStatusBarInnerClassName
3330
3345
  }
3331
3346
  ) }) : null,
3332
3347
  /* @__PURE__ */ jsxs7("div", { className: "space-y-0.5", children: [
@@ -5256,7 +5271,8 @@ function ToolCallBlock({
5256
5271
  sessionStatus,
5257
5272
  level = 1,
5258
5273
  turnBlocks,
5259
- reasoning
5274
+ reasoning,
5275
+ customization
5260
5276
  }) {
5261
5277
  const [expanded, setExpanded] = useState12(false);
5262
5278
  const activeSessionId = useSessionStore((s) => s.activeSessionId);
@@ -5309,13 +5325,13 @@ function ToolCallBlock({
5309
5325
  const loadedSkillName = normalizedName === "LoadSkillTools" ? extractLoadedSkillName(toolCall) : null;
5310
5326
  const tone = getToolTone(toolCall.status);
5311
5327
  const displayName = getToolDisplayLabel(toolCall);
5312
- const Renderer = getRenderer(normalizedName);
5328
+ const Renderer = customization?.renderers?.tool?.[normalizedName] ?? getRenderer(normalizedName);
5313
5329
  const borderWidthClass = level === 2 ? "border-l-[2px]" : "border-l-[3px]";
5314
5330
  const indentClass = level === 2 ? "ml-3" : "ml-4";
5315
5331
  const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
5316
5332
  const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx19(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx19(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx19(X4, { size: 11 }) : /* @__PURE__ */ jsx19(Check, { size: 11 });
5317
5333
  const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
5318
- return /* @__PURE__ */ jsxs15("div", { className: cn(indentClass, "text-xs"), children: [
5334
+ return /* @__PURE__ */ jsxs15("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
5319
5335
  /* @__PURE__ */ jsxs15("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
5320
5336
  /* @__PURE__ */ jsxs15(
5321
5337
  "button",
@@ -5939,7 +5955,7 @@ function buildSessionFileUrl(sessionId, filePath) {
5939
5955
  `/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(filePath)}`
5940
5956
  );
5941
5957
  }
5942
- function UserMessageBubble({ message }) {
5958
+ function UserMessageBubble({ message, className }) {
5943
5959
  const activeSessionId = useSessionStore((state) => state.activeSessionId);
5944
5960
  const _textContent = getTextContent(message.content);
5945
5961
  const fileParts = getFileParts(message.content);
@@ -6008,7 +6024,7 @@ function UserMessageBubble({ message }) {
6008
6024
  const mode = kind === "text" ? lower2.endsWith(".md") ? "markdown" : "text" : "default";
6009
6025
  setPreview({ filename: attachment.name, url, mode });
6010
6026
  };
6011
- return /* @__PURE__ */ jsx27("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs22("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6027
+ return /* @__PURE__ */ jsx27("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs22("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6012
6028
  (imageParts.length > 0 || imageTextAttachments.length > 0) && /* @__PURE__ */ jsxs22("div", { className: "grid gap-2", children: [
6013
6029
  imageParts.map((part, idx) => /* @__PURE__ */ jsx27(
6014
6030
  "button",
@@ -6096,10 +6112,13 @@ function UserMessageBubble({ message }) {
6096
6112
  )
6097
6113
  ] }) });
6098
6114
  }
6099
- function ErrorMessageBlock({ message }) {
6115
+ function ErrorMessageBlock({
6116
+ message,
6117
+ className
6118
+ }) {
6100
6119
  const text = getTextContent(message.content);
6101
6120
  const looksLikeModelUnavailable = /no source matches this model|404/i.test(text);
6102
- return /* @__PURE__ */ jsx27("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxs22("div", { className: "max-w-[85%] border-l-[3px] border-[hsl(var(--destructive))] px-4 py-1 text-sm leading-7 text-[hsl(var(--destructive))]", children: [
6121
+ return /* @__PURE__ */ jsx27("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ jsxs22("div", { className: "max-w-[85%] border-l-[3px] border-[hsl(var(--destructive))] px-4 py-1 text-sm leading-7 text-[hsl(var(--destructive))]", children: [
6103
6122
  text,
6104
6123
  looksLikeModelUnavailable ? /* @__PURE__ */ jsx27("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
6105
6124
  ] }) });
@@ -6639,7 +6658,8 @@ function AssistantTurnBlock({
6639
6658
  onAnswer,
6640
6659
  sessionStatus,
6641
6660
  level = 1,
6642
- forceExpanded = false
6661
+ forceExpanded = false,
6662
+ customization
6643
6663
  }) {
6644
6664
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
6645
6665
  const allToolCalls = useMemo14(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
@@ -6670,60 +6690,72 @@ function AssistantTurnBlock({
6670
6690
  const hasInterruptedState = messages.some((message) => message.status === "interrupted");
6671
6691
  const effectiveMode = isStreaming ? "detail" : displayMode === "compact" && hasActionableToolCall ? "detail" : displayMode;
6672
6692
  const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
6673
- return /* @__PURE__ */ jsxs24("div", { className: cn("flex flex-col gap-3", level === 2 && "gap-2.5"), children: [
6674
- memoryRefs.length > 0 && /* @__PURE__ */ jsx29(MemoryRefsHint, { refs: memoryRefs }),
6675
- hasInterruptedState && /* @__PURE__ */ jsx29("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
6676
- !isStreaming && /* @__PURE__ */ jsx29("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs24(
6677
- "button",
6678
- {
6679
- type: "button",
6680
- onClick: () => setDisplayMode(displayMode === "detail" ? "compact" : "detail"),
6681
- className: "inline-flex shrink-0 items-center gap-1 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
6682
- children: [
6683
- /* @__PURE__ */ jsx29("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
6684
- /* @__PURE__ */ jsx29(
6685
- ChevronRight5,
6686
- {
6687
- size: 18,
6688
- className: cn("transition-transform", effectiveMode === "detail" && "rotate-180")
6689
- }
6690
- )
6691
- ]
6692
- }
6693
- ) }),
6694
- effectiveMode === "detail" ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx29(
6695
- AssistantMessages,
6696
- {
6697
- messages,
6698
- isStreaming,
6699
- sessionId,
6700
- askAnswers,
6701
- onAnswer,
6702
- sessionStatus,
6703
- level,
6704
- showToolDetails: true
6705
- }
6706
- ) }) : /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4", children: [
6707
- resourceBlocks.length > 0 ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
6708
- finalMessage ? /* @__PURE__ */ jsx29(
6709
- "div",
6710
- {
6711
- className: cn(
6712
- resourceBlocks.length > 0 && "border-t border-[hsl(var(--border))] pt-4"
6713
- ),
6714
- children: /* @__PURE__ */ jsx29(
6715
- AssistantMessageContent,
6693
+ return /* @__PURE__ */ jsxs24(
6694
+ "div",
6695
+ {
6696
+ className: cn(
6697
+ "flex flex-col gap-3",
6698
+ level === 2 && "gap-2.5",
6699
+ customization?.classNames?.assistantTurn
6700
+ ),
6701
+ children: [
6702
+ memoryRefs.length > 0 && /* @__PURE__ */ jsx29(MemoryRefsHint, { refs: memoryRefs }),
6703
+ hasInterruptedState && /* @__PURE__ */ jsx29("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
6704
+ !isStreaming && /* @__PURE__ */ jsx29("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs24(
6705
+ "button",
6706
+ {
6707
+ type: "button",
6708
+ onClick: () => setDisplayMode(displayMode === "detail" ? "compact" : "detail"),
6709
+ className: "inline-flex shrink-0 items-center gap-1 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
6710
+ children: [
6711
+ /* @__PURE__ */ jsx29("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
6712
+ /* @__PURE__ */ jsx29(
6713
+ ChevronRight5,
6714
+ {
6715
+ size: 18,
6716
+ className: cn("transition-transform", effectiveMode === "detail" && "rotate-180")
6717
+ }
6718
+ )
6719
+ ]
6720
+ }
6721
+ ) }),
6722
+ effectiveMode === "detail" ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx29(
6723
+ AssistantMessages,
6724
+ {
6725
+ messages,
6726
+ isStreaming,
6727
+ sessionId,
6728
+ askAnswers,
6729
+ onAnswer,
6730
+ sessionStatus,
6731
+ level,
6732
+ showToolDetails: true,
6733
+ customization
6734
+ }
6735
+ ) }) : /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4", children: [
6736
+ resourceBlocks.length > 0 ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
6737
+ finalMessage ? /* @__PURE__ */ jsx29(
6738
+ "div",
6716
6739
  {
6717
- message: finalMessage,
6718
- isStreaming: isStreaming && finalMessage === messages[messages.length - 1],
6719
- sessionId,
6720
- reasoning: finalMessage.reasoning
6740
+ className: cn(
6741
+ resourceBlocks.length > 0 && "border-t border-[hsl(var(--border))] pt-4"
6742
+ ),
6743
+ children: /* @__PURE__ */ jsx29(
6744
+ AssistantMessageContent,
6745
+ {
6746
+ message: finalMessage,
6747
+ isStreaming: isStreaming && finalMessage === messages[messages.length - 1],
6748
+ sessionId,
6749
+ reasoning: finalMessage.reasoning,
6750
+ className: customization?.classNames?.assistantText
6751
+ }
6752
+ )
6721
6753
  }
6722
- )
6723
- }
6724
- ) : isStreaming ? /* @__PURE__ */ jsx29("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
6725
- ] }) })
6726
- ] });
6754
+ ) : isStreaming ? /* @__PURE__ */ jsx29("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
6755
+ ] }) })
6756
+ ]
6757
+ }
6758
+ );
6727
6759
  }
6728
6760
  function AssistantMessages({
6729
6761
  messages,
@@ -6733,7 +6765,8 @@ function AssistantMessages({
6733
6765
  onAnswer,
6734
6766
  sessionStatus,
6735
6767
  level,
6736
- showToolDetails
6768
+ showToolDetails,
6769
+ customization
6737
6770
  }) {
6738
6771
  return messages.map(
6739
6772
  (message, index) => isRenderableAssistantMessage(message, isStreaming && index === messages.length - 1) ? (() => {
@@ -6763,7 +6796,8 @@ function AssistantMessages({
6763
6796
  message,
6764
6797
  isStreaming: isStreamingLastMessage,
6765
6798
  sessionId,
6766
- reasoning: contentReasoning
6799
+ reasoning: contentReasoning,
6800
+ className: customization?.classNames?.assistantText
6767
6801
  }
6768
6802
  ),
6769
6803
  hasToolCalls && showToolDetails && /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
@@ -6779,7 +6813,8 @@ function AssistantMessages({
6779
6813
  askAnswers,
6780
6814
  onAnswer,
6781
6815
  turnBlocks: message.blocks,
6782
- level
6816
+ level,
6817
+ customization
6783
6818
  },
6784
6819
  item.key
6785
6820
  );
@@ -6793,6 +6828,21 @@ function AssistantMessages({
6793
6828
  reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
6794
6829
  },
6795
6830
  toolCall.id
6831
+ ) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx29(
6832
+ customization.components.ToolCall,
6833
+ {
6834
+ toolCall,
6835
+ answerData: askAnswers?.[toolCall.id],
6836
+ onAnswer,
6837
+ answered: sessionStatus !== "waiting_for_input",
6838
+ sessionId,
6839
+ sessionStatus,
6840
+ level,
6841
+ turnBlocks: message.blocks,
6842
+ reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0,
6843
+ customization
6844
+ },
6845
+ toolCall.id
6796
6846
  ) : /* @__PURE__ */ jsx29(
6797
6847
  ToolCallBlock,
6798
6848
  {
@@ -6804,7 +6854,8 @@ function AssistantMessages({
6804
6854
  sessionStatus,
6805
6855
  level,
6806
6856
  turnBlocks: message.blocks,
6807
- reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
6857
+ reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0,
6858
+ customization
6808
6859
  },
6809
6860
  toolCall.id
6810
6861
  );
@@ -6842,7 +6893,8 @@ function CompactToolGroupBlock({
6842
6893
  askAnswers,
6843
6894
  onAnswer,
6844
6895
  turnBlocks,
6845
- level
6896
+ level,
6897
+ customization
6846
6898
  }) {
6847
6899
  const [expanded, setExpanded] = useState16(false);
6848
6900
  const indentClass = level === 2 ? "ml-3" : "ml-4";
@@ -6905,27 +6957,46 @@ function CompactToolGroupBlock({
6905
6957
  reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
6906
6958
  totalDurationMs > 0 ? /* @__PURE__ */ jsx29("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
6907
6959
  ] }),
6908
- expanded ? /* @__PURE__ */ jsx29("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => /* @__PURE__ */ jsx29(
6909
- ToolCallBlock,
6910
- {
6911
- toolCall,
6912
- answerData: askAnswers?.[toolCall.id],
6913
- onAnswer,
6914
- answered: sessionStatus !== "waiting_for_input",
6915
- sessionId,
6916
- sessionStatus,
6917
- level,
6918
- turnBlocks
6919
- },
6920
- toolCall.id
6921
- )) }) : null
6960
+ expanded ? /* @__PURE__ */ jsx29("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
6961
+ const CustomToolCall = customization?.components?.ToolCall;
6962
+ return CustomToolCall ? /* @__PURE__ */ jsx29(
6963
+ CustomToolCall,
6964
+ {
6965
+ toolCall,
6966
+ answerData: askAnswers?.[toolCall.id],
6967
+ onAnswer,
6968
+ answered: sessionStatus !== "waiting_for_input",
6969
+ sessionId,
6970
+ sessionStatus,
6971
+ level,
6972
+ turnBlocks,
6973
+ customization
6974
+ },
6975
+ toolCall.id
6976
+ ) : /* @__PURE__ */ jsx29(
6977
+ ToolCallBlock,
6978
+ {
6979
+ toolCall,
6980
+ answerData: askAnswers?.[toolCall.id],
6981
+ onAnswer,
6982
+ answered: sessionStatus !== "waiting_for_input",
6983
+ sessionId,
6984
+ sessionStatus,
6985
+ level,
6986
+ turnBlocks,
6987
+ customization
6988
+ },
6989
+ toolCall.id
6990
+ );
6991
+ }) }) : null
6922
6992
  ] });
6923
6993
  }
6924
6994
  function AssistantMessageContent({
6925
6995
  message,
6926
6996
  isStreaming,
6927
6997
  sessionId,
6928
- reasoning
6998
+ reasoning,
6999
+ className
6929
7000
  }) {
6930
7001
  const fileParts = getFileParts(message.content);
6931
7002
  const imageParts = getImageParts(message.content);
@@ -6950,7 +7021,8 @@ function AssistantMessageContent({
6950
7021
  text,
6951
7022
  sessionId,
6952
7023
  messageId: message.entry_id,
6953
- reasoning
7024
+ reasoning,
7025
+ className
6954
7026
  }
6955
7027
  ) : null,
6956
7028
  !text && isStreaming && /* @__PURE__ */ jsx29("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
@@ -6961,7 +7033,8 @@ function AssistantText({
6961
7033
  text,
6962
7034
  sessionId,
6963
7035
  messageId,
6964
- reasoning
7036
+ reasoning,
7037
+ className
6965
7038
  }) {
6966
7039
  const sendMessage = useCallback11(
6967
7040
  async (content) => {
@@ -6973,7 +7046,7 @@ function AssistantText({
6973
7046
  () => ({ sessionId, messageId, sendMessage }),
6974
7047
  [sessionId, messageId, sendMessage]
6975
7048
  );
6976
- return /* @__PURE__ */ jsxs24("div", { className: "text-[15px] leading-8 text-[hsl(var(--foreground))]", children: [
7049
+ return /* @__PURE__ */ jsxs24("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
6977
7050
  /* @__PURE__ */ jsx29(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx29(
6978
7051
  MarkdownContent,
6979
7052
  {
@@ -7533,7 +7606,8 @@ function MessageList({
7533
7606
  messages: rawMessages,
7534
7607
  onAnswer,
7535
7608
  sessionStatus,
7536
- onConfirmPlan
7609
+ onConfirmPlan,
7610
+ customization
7537
7611
  }) {
7538
7612
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
7539
7613
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId]);
@@ -7697,35 +7771,43 @@ function MessageList({
7697
7771
  const handleSelectTurn = useCallback12((turnId) => {
7698
7772
  document.getElementById(turnId)?.scrollIntoView({ behavior: "smooth", block: "start" });
7699
7773
  }, []);
7700
- return /* @__PURE__ */ jsxs29("div", { ref: containerRef, className: "relative min-h-0 flex-1", children: [
7701
- turnNavItems.length > 1 ? /* @__PURE__ */ jsx34(
7702
- TurnNavRail,
7703
- {
7704
- items: turnNavItems,
7705
- activeTurnId: activeTurnId ?? lastTurnId,
7706
- onSelectTurn: handleSelectTurn
7707
- }
7708
- ) : null,
7709
- /* @__PURE__ */ jsxs29(StickToBottom, { className: "h-full overflow-y-hidden", resize: "smooth", children: [
7710
- /* @__PURE__ */ jsx34(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx34(
7711
- MessageListContent,
7712
- {
7713
- askAnswers,
7714
- hasInterruptedTurn,
7715
- lastTurnId,
7716
- layoutSignature,
7717
- messages,
7718
- onAnswer,
7719
- onConfirmPlan,
7720
- renderBlocks,
7721
- sessionId,
7722
- sessionStatus,
7723
- stickyTurn
7724
- }
7725
- ) }),
7726
- /* @__PURE__ */ jsx34(ScrollToBottomButton, {})
7727
- ] })
7728
- ] });
7774
+ return /* @__PURE__ */ jsxs29(
7775
+ "div",
7776
+ {
7777
+ ref: containerRef,
7778
+ className: `relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? ""}`,
7779
+ children: [
7780
+ turnNavItems.length > 1 ? /* @__PURE__ */ jsx34(
7781
+ TurnNavRail,
7782
+ {
7783
+ items: turnNavItems,
7784
+ activeTurnId: activeTurnId ?? lastTurnId,
7785
+ onSelectTurn: handleSelectTurn
7786
+ }
7787
+ ) : null,
7788
+ /* @__PURE__ */ jsxs29(StickToBottom, { className: "h-full overflow-y-hidden", resize: "smooth", children: [
7789
+ /* @__PURE__ */ jsx34(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx34(
7790
+ MessageListContent,
7791
+ {
7792
+ askAnswers,
7793
+ hasInterruptedTurn,
7794
+ lastTurnId,
7795
+ layoutSignature,
7796
+ messages,
7797
+ onAnswer,
7798
+ onConfirmPlan,
7799
+ renderBlocks,
7800
+ sessionId,
7801
+ sessionStatus,
7802
+ stickyTurn,
7803
+ customization
7804
+ }
7805
+ ) }),
7806
+ /* @__PURE__ */ jsx34(ScrollToBottomButton, {})
7807
+ ] })
7808
+ ]
7809
+ }
7810
+ );
7729
7811
  }
7730
7812
  function MessageListContent({
7731
7813
  askAnswers,
@@ -7738,7 +7820,8 @@ function MessageListContent({
7738
7820
  renderBlocks,
7739
7821
  sessionId,
7740
7822
  sessionStatus,
7741
- stickyTurn
7823
+ stickyTurn,
7824
+ customization
7742
7825
  }) {
7743
7826
  const { scrollToBottom } = useStickToBottomContext();
7744
7827
  const handleJumpToLatest = useCallback12(() => {
@@ -7748,7 +7831,7 @@ function MessageListContent({
7748
7831
  }
7749
7832
  scrollToBottom();
7750
7833
  }, [lastTurnId, scrollToBottom]);
7751
- return /* @__PURE__ */ jsx34("div", { className: "mx-auto max-w-3xl", children: /* @__PURE__ */ jsxs29("div", { className: "min-w-0 flex flex-col gap-8", children: [
7834
+ return /* @__PURE__ */ jsx34("div", { className: `mx-auto max-w-3xl ${customization?.classNames?.messageListContent ?? ""}`, children: /* @__PURE__ */ jsxs29("div", { className: `min-w-0 flex flex-col gap-8 ${customization?.classNames?.messageListInner ?? ""}`, children: [
7752
7835
  stickyTurn ? /* @__PURE__ */ jsx34(
7753
7836
  StickyStatusBar,
7754
7837
  {
@@ -7759,13 +7842,37 @@ function MessageListContent({
7759
7842
  onJumpToLatest: handleJumpToLatest
7760
7843
  }
7761
7844
  ) : null,
7762
- renderBlocks.length === 0 ? /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))]", children: [
7845
+ renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */ jsx34(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs29("div", { className: `flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`, children: [
7763
7846
  /* @__PURE__ */ jsx34(MessageSquare, { size: 40, strokeWidth: 1.5 }),
7764
7847
  /* @__PURE__ */ jsx34("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
7765
7848
  /* @__PURE__ */ jsx34("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
7766
7849
  ] }) : renderBlocks.map((block, blockIndex) => {
7767
7850
  if (block.type === "message") {
7768
- return /* @__PURE__ */ jsx34("div", { className: "msg-animate", children: isUserMessage(block.message) ? /* @__PURE__ */ jsx34(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx34(ErrorMessageBlock, { message: block.message }) : null }, block.key);
7851
+ return /* @__PURE__ */ jsx34("div", { className: "msg-animate", children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx34(
7852
+ customization.components.UserMessage,
7853
+ {
7854
+ message: block.message,
7855
+ className: customization.classNames?.userMessage
7856
+ }
7857
+ ) : /* @__PURE__ */ jsx34(
7858
+ UserMessageBubble,
7859
+ {
7860
+ message: block.message,
7861
+ className: customization?.classNames?.userMessage
7862
+ }
7863
+ ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx34(
7864
+ customization.components.ErrorMessage,
7865
+ {
7866
+ message: block.message,
7867
+ className: customization.classNames?.errorMessage
7868
+ }
7869
+ ) : /* @__PURE__ */ jsx34(
7870
+ ErrorMessageBlock,
7871
+ {
7872
+ message: block.message,
7873
+ className: customization?.classNames?.errorMessage
7874
+ }
7875
+ ) : null }, block.key);
7769
7876
  }
7770
7877
  if (block.type === "assistant_turn") {
7771
7878
  const nextBlock = renderBlocks[blockIndex + 1];
@@ -7789,7 +7896,20 @@ function MessageListContent({
7789
7896
  label: "\u52A9\u624B\u6D88\u606F",
7790
7897
  details: block.key,
7791
7898
  resetKey: getMessagesRenderSignature(block.messages),
7792
- children: /* @__PURE__ */ jsx34(
7899
+ children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx34(
7900
+ customization.components.AssistantTurn,
7901
+ {
7902
+ turnKey: block.key,
7903
+ sessionId,
7904
+ messages: block.messages,
7905
+ isStreaming: block.isStreaming,
7906
+ isLastTurn: block.anchorId === lastTurnId,
7907
+ askAnswers,
7908
+ onAnswer,
7909
+ sessionStatus,
7910
+ customization
7911
+ }
7912
+ ) : /* @__PURE__ */ jsx34(
7793
7913
  AssistantTurnBlock,
7794
7914
  {
7795
7915
  turnKey: block.key,
@@ -7799,7 +7919,8 @@ function MessageListContent({
7799
7919
  isLastTurn: block.anchorId === lastTurnId,
7800
7920
  askAnswers,
7801
7921
  onAnswer,
7802
- sessionStatus
7922
+ sessionStatus,
7923
+ customization
7803
7924
  }
7804
7925
  )
7805
7926
  }
@@ -7877,7 +7998,10 @@ function ChatView({
7877
7998
  onCommand,
7878
7999
  canShareSession = false,
7879
8000
  onResyncSkills,
7880
- isResyncingSkills = false
8001
+ isResyncingSkills = false,
8002
+ classNames,
8003
+ components,
8004
+ renderers
7881
8005
  }) {
7882
8006
  const {
7883
8007
  messages,
@@ -7903,8 +8027,10 @@ function ChatView({
7903
8027
  },
7904
8028
  [send]
7905
8029
  );
7906
- return /* @__PURE__ */ jsxs30("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: [
7907
- isViewer && /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
8030
+ const customization = { classNames, components, renderers };
8031
+ const SkillStatus = components?.SkillStatusBar;
8032
+ return /* @__PURE__ */ jsxs30("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
8033
+ isViewer && /* @__PURE__ */ jsxs30("div", { className: `flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))] ${classNames?.viewerBanner ?? ""}`, children: [
7908
8034
  /* @__PURE__ */ jsx35(Eye, { size: 14 }),
7909
8035
  "\u4F60\u6B63\u5728\u67E5\u770B\u5206\u4EAB\u7684\u4F1A\u8BDD\uFF08\u53EA\u8BFB\uFF09"
7910
8036
  ] }),
@@ -7916,7 +8042,8 @@ function ChatView({
7916
8042
  messages,
7917
8043
  onAnswer: isViewer ? void 0 : (msg, toolCallId, answerData) => send(msg, mode, { tool_call_id: toolCallId, ...answerData }),
7918
8044
  sessionStatus,
7919
- onConfirmPlan: isViewer ? void 0 : onConfirmPlan
8045
+ onConfirmPlan: isViewer ? void 0 : onConfirmPlan,
8046
+ customization
7920
8047
  },
7921
8048
  sessionId
7922
8049
  ),
@@ -7932,6 +8059,11 @@ function ChatView({
7932
8059
  onBeforeSend,
7933
8060
  onCommand,
7934
8061
  canShareSession,
8062
+ className: classNames?.chatInputRoot,
8063
+ innerClassName: classNames?.chatInputInner,
8064
+ SkillStatusBarComponent: SkillStatus,
8065
+ skillStatusBarClassName: classNames?.skillStatusBarRoot,
8066
+ skillStatusBarInnerClassName: classNames?.skillStatusBarInner,
7935
8067
  onResyncSkills,
7936
8068
  isResyncingSkills
7937
8069
  }
@@ -7989,4 +8121,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
7989
8121
  * Licensed under the MIT License. See License.txt in the project root for license information.
7990
8122
  *--------------------------------------------------------------------------------------------*)
7991
8123
  */
7992
- //# sourceMappingURL=chunk-LIL4FIZP.js.map
8124
+ //# sourceMappingURL=chunk-CGOQI7ZL.js.map