@arcote.tech/arc-ds 0.7.10 → 0.7.12

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arcote.tech/arc-ds",
3
3
  "type": "module",
4
- "version": "0.7.10",
4
+ "version": "0.7.12",
5
5
  "private": false,
6
6
  "author": "Przemysław Krasiński [arcote.tech]",
7
7
  "description": "Design System for Arc framework — CVA-based components with display modes and variant overrides",
@@ -30,7 +30,7 @@
30
30
  "tailwind-merge": "^3.5.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "@arcote.tech/arc": "^0.7.10",
33
+ "@arcote.tech/arc": "^0.7.12",
34
34
  "framer-motion": "^12.0.0",
35
35
  "lucide-react": ">=0.400.0",
36
36
  "radix-ui": "^1.0.0",
@@ -32,6 +32,9 @@ export interface ChatLabels {
32
32
  errorLabel: string;
33
33
  // askQuestions tool view
34
34
  answerBelowLabel: ReactNode;
35
+ // Interrupted generation (server restart / stream lost) + retry button
36
+ interruptedLabel: ReactNode;
37
+ retryLabel: ReactNode;
35
38
  // completeStage tool view
36
39
  stageCompleteLabel: ReactNode;
37
40
  advanceStageLabel: ReactNode;
@@ -62,6 +65,8 @@ export const defaultChatLabels: ChatLabels = {
62
65
  toolDoneLabel: "Done",
63
66
  errorLabel: "Error",
64
67
  answerBelowLabel: "Answer the questions below",
68
+ interruptedLabel: "Generation interrupted",
69
+ retryLabel: "Retry",
65
70
  stageCompleteLabel: "Stage complete",
66
71
  advanceStageLabel: "Go to next stage",
67
72
  continueStageLabel: "Keep talking",
@@ -1,7 +1,7 @@
1
1
  import ReactMarkdown from "react-markdown";
2
2
  import remarkGfm from "remark-gfm";
3
3
  import { Button } from "../button/button";
4
- import { Bot, User, MessageSquare } from "lucide-react";
4
+ import { Bot, User, MessageSquare, Loader2 } from "lucide-react";
5
5
  import type { ChatMessageData } from "./types";
6
6
  import { ToolUseBlock } from "./tool-use-block";
7
7
  import { useChatLabels } from "./chat-labels";
@@ -21,6 +21,12 @@ export function ChatMessage({
21
21
  const isUser = message.role === "user";
22
22
  const hasUnansweredQuestions =
23
23
  message.questions && message.questions.length > 0;
24
+ // Empty assistant bubble in streaming state = LLM still thinking / waiting
25
+ // for first chunk. Show a spinner so the UI doesn't look frozen — the
26
+ // pulsing caret on `data-streaming` only works once there's a `last-child`
27
+ // to attach to.
28
+ const showStreamingPlaceholder =
29
+ !isUser && message.isStreaming && !message.content;
24
30
 
25
31
  return (
26
32
  <div className={`flex gap-3 ${isUser ? "flex-row-reverse" : ""}`}>
@@ -48,13 +54,18 @@ export function ChatMessage({
48
54
  : "bg-card border border-border rounded-tl-sm"
49
55
  }`}
50
56
  >
51
- <div
52
- data-streaming={message.isStreaming || undefined}
53
- className="chat-markdown space-y-2 text-left [&_p]:m-0 [&_ul]:my-1 [&_ul]:pl-5 [&_ol]:my-1 [&_ol]:pl-5 [&_li]:my-0.5 [&_a]:text-primary [&_a]:underline [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-xs [&_pre]:bg-muted [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto [&_strong]:font-semibold [&_em]:italic [&_h1]:text-base [&_h1]:font-semibold [&_h2]:text-sm [&_h2]:font-semibold [&_h3]:text-sm [&_h3]:font-medium [&_blockquote]:border-l-2 [&_blockquote]:border-primary/30 [&_blockquote]:pl-3 [&_blockquote]:italic data-[streaming]:[&_>*:last-child]:after:content-[''] data-[streaming]:[&_>*:last-child]:after:inline-block data-[streaming]:[&_>*:last-child]:after:w-[0.4em] data-[streaming]:[&_>*:last-child]:after:h-[1em] data-[streaming]:[&_>*:last-child]:after:bg-foreground/60 data-[streaming]:[&_>*:last-child]:after:animate-pulse data-[streaming]:[&_>*:last-child]:after:ml-0.5 data-[streaming]:[&_>*:last-child]:after:align-text-bottom">
54
- <ReactMarkdown remarkPlugins={[remarkGfm]}>
55
- {message.content}
56
- </ReactMarkdown>
57
- </div>
57
+ {showStreamingPlaceholder ? (
58
+ <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
59
+ ) : (
60
+ <div
61
+ data-streaming={message.isStreaming || undefined}
62
+ className="chat-markdown space-y-2 text-left [&_p]:m-0 [&_ul]:my-1 [&_ul]:pl-5 [&_ol]:my-1 [&_ol]:pl-5 [&_li]:my-0.5 [&_a]:text-primary [&_a]:underline [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-xs [&_pre]:bg-muted [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto [&_strong]:font-semibold [&_em]:italic [&_h1]:text-base [&_h1]:font-semibold [&_h2]:text-sm [&_h2]:font-semibold [&_h3]:text-sm [&_h3]:font-medium [&_blockquote]:border-l-2 [&_blockquote]:border-primary/30 [&_blockquote]:pl-3 [&_blockquote]:italic data-[streaming]:[&_>*:last-child]:after:content-[''] data-[streaming]:[&_>*:last-child]:after:inline-block data-[streaming]:[&_>*:last-child]:after:w-[0.4em] data-[streaming]:[&_>*:last-child]:after:h-[1em] data-[streaming]:[&_>*:last-child]:after:bg-foreground/60 data-[streaming]:[&_>*:last-child]:after:animate-pulse data-[streaming]:[&_>*:last-child]:after:ml-0.5 data-[streaming]:[&_>*:last-child]:after:align-text-bottom"
63
+ >
64
+ <ReactMarkdown remarkPlugins={[remarkGfm]}>
65
+ {message.content}
66
+ </ReactMarkdown>
67
+ </div>
68
+ )}
58
69
  </div>
59
70
 
60
71
  {/* Tool uses */}