@wallarm-org/design-system 3.2.0 → 3.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.
Files changed (169) hide show
  1. package/dist/components/AnimatedBackground/blur/BlurBackground.d.ts +6 -0
  2. package/dist/components/AnimatedBackground/blur/BlurBackground.js +176 -76
  3. package/dist/components/AnimatedBackground/blur/index.d.ts +1 -1
  4. package/dist/components/AnimatedBackground/index.d.ts +1 -1
  5. package/dist/components/ApprovalCard/ApprovalCard.d.ts +13 -0
  6. package/dist/components/ApprovalCard/ApprovalCard.js +249 -0
  7. package/dist/components/ApprovalCard/ApprovalCardActions.d.ts +6 -0
  8. package/dist/components/ApprovalCard/ApprovalCardActions.js +50 -0
  9. package/dist/components/ApprovalCard/ApprovalCardContent.d.ts +6 -0
  10. package/dist/components/ApprovalCard/ApprovalCardContent.js +50 -0
  11. package/dist/components/ApprovalCard/classes.d.ts +10 -0
  12. package/dist/components/ApprovalCard/classes.js +26 -0
  13. package/dist/components/ApprovalCard/index.d.ts +3 -0
  14. package/dist/components/ApprovalCard/index.js +3 -0
  15. package/dist/components/AssistantMessage/AssistantMessage.d.ts +12 -0
  16. package/dist/components/AssistantMessage/AssistantMessage.js +66 -0
  17. package/dist/components/AssistantMessage/AssistantMessageContent.d.ts +10 -0
  18. package/dist/components/AssistantMessage/AssistantMessageContent.js +50 -0
  19. package/dist/components/AssistantMessage/AssistantMessageError.d.ts +13 -0
  20. package/dist/components/AssistantMessage/AssistantMessageError.js +93 -0
  21. package/dist/components/AssistantMessage/AssistantMessageLoader.d.ts +13 -0
  22. package/dist/components/AssistantMessage/AssistantMessageLoader.js +88 -0
  23. package/dist/components/AssistantMessage/AssistantMessageMarkdown.d.ts +71 -0
  24. package/dist/components/AssistantMessage/AssistantMessageMarkdown.js +278 -0
  25. package/dist/components/AssistantMessage/AssistantMessageMarkdownCodeBlock.d.ts +17 -0
  26. package/dist/components/AssistantMessage/AssistantMessageMarkdownCodeBlock.js +94 -0
  27. package/dist/components/AssistantMessage/AssistantMessageMarkdownInlineCode.d.ts +10 -0
  28. package/dist/components/AssistantMessage/AssistantMessageMarkdownInlineCode.js +59 -0
  29. package/dist/components/AssistantMessage/AssistantMessageMarkdownLink.d.ts +14 -0
  30. package/dist/components/AssistantMessage/AssistantMessageMarkdownLink.js +65 -0
  31. package/dist/components/AssistantMessage/AssistantMessageMarkdownTable.d.ts +7 -0
  32. package/dist/components/AssistantMessage/AssistantMessageMarkdownTable.js +70 -0
  33. package/dist/components/AssistantMessage/classes.d.ts +38 -0
  34. package/dist/components/AssistantMessage/classes.js +46 -0
  35. package/dist/components/AssistantMessage/index.d.ts +9 -0
  36. package/dist/components/AssistantMessage/index.js +9 -0
  37. package/dist/components/AssistantMessage/lib/markdown.d.ts +20 -0
  38. package/dist/components/AssistantMessage/lib/markdown.js +51 -0
  39. package/dist/components/ChainOfThought/ChainOfThought.d.ts +10 -0
  40. package/dist/components/ChainOfThought/ChainOfThought.js +66 -0
  41. package/dist/components/ChainOfThought/ChainOfThoughtStep.d.ts +31 -0
  42. package/dist/components/ChainOfThought/ChainOfThoughtStep.js +312 -0
  43. package/dist/components/ChainOfThought/classes.d.ts +20 -0
  44. package/dist/components/ChainOfThought/classes.js +84 -0
  45. package/dist/components/ChainOfThought/index.d.ts +2 -0
  46. package/dist/components/ChainOfThought/index.js +2 -0
  47. package/dist/components/Chat/Chat.d.ts +12 -0
  48. package/dist/components/Chat/Chat.js +90 -0
  49. package/dist/components/Chat/ChatBody.d.ts +12 -0
  50. package/dist/components/Chat/ChatBody.js +52 -0
  51. package/dist/components/Chat/ChatFooter.d.ts +7 -0
  52. package/dist/components/Chat/ChatFooter.js +50 -0
  53. package/dist/components/Chat/ChatGreeting.d.ts +8 -0
  54. package/dist/components/Chat/ChatGreeting.js +94 -0
  55. package/dist/components/Chat/ChatHeader.d.ts +6 -0
  56. package/dist/components/Chat/ChatHeader.js +50 -0
  57. package/dist/components/Chat/ChatHeaderActions.d.ts +7 -0
  58. package/dist/components/Chat/ChatHeaderActions.js +50 -0
  59. package/dist/components/Chat/ChatHeaderTitle.d.ts +12 -0
  60. package/dist/components/Chat/ChatHeaderTitle.js +99 -0
  61. package/dist/components/Chat/ChatSuggestion.d.ts +7 -0
  62. package/dist/components/Chat/ChatSuggestion.js +56 -0
  63. package/dist/components/Chat/ChatSuggestions.d.ts +14 -0
  64. package/dist/components/Chat/ChatSuggestions.js +111 -0
  65. package/dist/components/Chat/ChatSuggestionsContext.d.ts +7 -0
  66. package/dist/components/Chat/ChatSuggestionsContext.js +7 -0
  67. package/dist/components/Chat/ChatTrigger.d.ts +13 -0
  68. package/dist/components/Chat/ChatTrigger.js +101 -0
  69. package/dist/components/Chat/classes.d.ts +17 -0
  70. package/dist/components/Chat/classes.js +44 -0
  71. package/dist/components/Chat/index.d.ts +10 -0
  72. package/dist/components/Chat/index.js +10 -0
  73. package/dist/components/ChatInput/ChatInput.d.ts +30 -0
  74. package/dist/components/ChatInput/ChatInput.js +230 -0
  75. package/dist/components/ChatInput/ChatInputContext.d.ts +11 -0
  76. package/dist/components/ChatInput/ChatInputContext.js +8 -0
  77. package/dist/components/ChatInput/ChatInputSubmit.d.ts +10 -0
  78. package/dist/components/ChatInput/ChatInputSubmit.js +175 -0
  79. package/dist/components/ChatInput/ChatInputTextarea.d.ts +6 -0
  80. package/dist/components/ChatInput/ChatInputTextarea.js +155 -0
  81. package/dist/components/ChatInput/classes.d.ts +9 -0
  82. package/dist/components/ChatInput/classes.js +22 -0
  83. package/dist/components/ChatInput/index.d.ts +3 -0
  84. package/dist/components/ChatInput/index.js +3 -0
  85. package/dist/components/ChatPermissions/ChatPermissions.d.ts +12 -0
  86. package/dist/components/ChatPermissions/ChatPermissions.js +66 -0
  87. package/dist/components/ChatPermissions/ChatPermissionsContent.d.ts +7 -0
  88. package/dist/components/ChatPermissions/ChatPermissionsContent.js +73 -0
  89. package/dist/components/ChatPermissions/ChatPermissionsContext.d.ts +7 -0
  90. package/dist/components/ChatPermissions/ChatPermissionsContext.js +8 -0
  91. package/dist/components/ChatPermissions/ChatPermissionsItem.d.ts +17 -0
  92. package/dist/components/ChatPermissions/ChatPermissionsItem.js +115 -0
  93. package/dist/components/ChatPermissions/ChatPermissionsTrigger.d.ts +6 -0
  94. package/dist/components/ChatPermissions/ChatPermissionsTrigger.js +110 -0
  95. package/dist/components/ChatPermissions/classes.d.ts +3 -0
  96. package/dist/components/ChatPermissions/classes.js +5 -0
  97. package/dist/components/ChatPermissions/index.d.ts +4 -0
  98. package/dist/components/ChatPermissions/index.js +4 -0
  99. package/dist/components/Conversation/Conversation.d.ts +19 -0
  100. package/dist/components/Conversation/Conversation.js +102 -0
  101. package/dist/components/Conversation/ConversationContent.d.ts +11 -0
  102. package/dist/components/Conversation/ConversationContent.js +103 -0
  103. package/dist/components/Conversation/ConversationContext.d.ts +14 -0
  104. package/dist/components/Conversation/ConversationContext.js +8 -0
  105. package/dist/components/Conversation/ConversationEmptyState.d.ts +15 -0
  106. package/dist/components/Conversation/ConversationEmptyState.js +70 -0
  107. package/dist/components/Conversation/ConversationScrollButton.d.ts +13 -0
  108. package/dist/components/Conversation/ConversationScrollButton.js +138 -0
  109. package/dist/components/Conversation/classes.d.ts +13 -0
  110. package/dist/components/Conversation/classes.js +8 -0
  111. package/dist/components/Conversation/index.d.ts +4 -0
  112. package/dist/components/Conversation/index.js +4 -0
  113. package/dist/components/Conversation/useStickToBottom.d.ts +9 -0
  114. package/dist/components/Conversation/useStickToBottom.js +203 -0
  115. package/dist/components/MessageActions/MessageAction.d.ts +18 -0
  116. package/dist/components/MessageActions/MessageAction.js +109 -0
  117. package/dist/components/MessageActions/MessageActions.d.ts +12 -0
  118. package/dist/components/MessageActions/MessageActions.js +74 -0
  119. package/dist/components/MessageActions/MessageTimestamp.d.ts +7 -0
  120. package/dist/components/MessageActions/MessageTimestamp.js +50 -0
  121. package/dist/components/MessageActions/classes.d.ts +5 -0
  122. package/dist/components/MessageActions/classes.js +15 -0
  123. package/dist/components/MessageActions/index.d.ts +3 -0
  124. package/dist/components/MessageActions/index.js +3 -0
  125. package/dist/components/Popover/PopoverContent.d.ts +2 -1
  126. package/dist/components/Popover/PopoverContent.js +42 -39
  127. package/dist/components/UserMessage/UserMessage.d.ts +10 -0
  128. package/dist/components/UserMessage/UserMessage.js +66 -0
  129. package/dist/components/UserMessage/UserMessageBubble.d.ts +16 -0
  130. package/dist/components/UserMessage/UserMessageBubble.js +175 -0
  131. package/dist/components/UserMessage/UserMessageContext.d.ts +9 -0
  132. package/dist/components/UserMessage/UserMessageContext.js +4 -0
  133. package/dist/components/UserMessage/UserMessageShowMore.d.ts +15 -0
  134. package/dist/components/UserMessage/UserMessageShowMore.js +87 -0
  135. package/dist/components/UserMessage/classes.d.ts +11 -0
  136. package/dist/components/UserMessage/classes.js +32 -0
  137. package/dist/components/UserMessage/index.d.ts +3 -0
  138. package/dist/components/UserMessage/index.js +3 -0
  139. package/dist/components/WallyAssistant/WallyAssistant.d.ts +56 -0
  140. package/dist/components/WallyAssistant/WallyAssistant.js +541 -0
  141. package/dist/components/WallyAssistant/index.d.ts +10 -0
  142. package/dist/components/WallyAssistant/index.js +8 -0
  143. package/dist/components/WallyAssistant/model/deriveChatState.d.ts +33 -0
  144. package/dist/components/WallyAssistant/model/deriveChatState.js +54 -0
  145. package/dist/components/WallyAssistant/model/labels.d.ts +43 -0
  146. package/dist/components/WallyAssistant/model/labels.js +33 -0
  147. package/dist/components/WallyAssistant/model/model.d.ts +184 -0
  148. package/dist/components/WallyAssistant/model/model.js +0 -0
  149. package/dist/components/WallyAssistant/views/ApprovalCardView.d.ts +20 -0
  150. package/dist/components/WallyAssistant/views/ApprovalCardView.js +274 -0
  151. package/dist/components/WallyAssistant/views/ChainOfThoughtView.d.ts +18 -0
  152. package/dist/components/WallyAssistant/views/ChainOfThoughtView.js +301 -0
  153. package/dist/components/WallyAssistant/views/ChatMessageView.d.ts +15 -0
  154. package/dist/components/WallyAssistant/views/ChatMessageView.js +372 -0
  155. package/dist/components/WallyAssistant/views/ChatPartView.d.ts +16 -0
  156. package/dist/components/WallyAssistant/views/ChatPartView.js +171 -0
  157. package/dist/components/WallyAssistant/views/ChatViewContext.d.ts +98 -0
  158. package/dist/components/WallyAssistant/views/ChatViewContext.js +44 -0
  159. package/dist/components/WallyAssistant/views/ChatViewProvider.d.ts +18 -0
  160. package/dist/components/WallyAssistant/views/ChatViewProvider.js +96 -0
  161. package/dist/components/WallyAssistant/views/stepIcons.d.ts +8 -0
  162. package/dist/components/WallyAssistant/views/stepIcons.js +47 -0
  163. package/dist/index.d.ts +10 -0
  164. package/dist/index.js +10 -0
  165. package/dist/metadata/components.json +30786 -15960
  166. package/dist/theme/components/animated-background.css +6 -1
  167. package/dist/theme/index.css +1 -0
  168. package/dist/theme/utilities/shimmer-text.css +27 -0
  169. package/package.json +3 -1
@@ -0,0 +1,54 @@
1
+ const LIVE_STEP_STATUSES = new Set([
2
+ 'pending',
3
+ 'running',
4
+ 'awaiting-approval'
5
+ ]);
6
+ const NO_APPROVALS = [];
7
+ const isRunningStatus = (status)=>'submitted' === status || 'streaming' === status;
8
+ const isLiveStepStatus = (status)=>LIVE_STEP_STATUSES.has(status);
9
+ const isLiveStep = (step)=>isLiveStepStatus(step.status) || (step.steps?.some(isLiveStep) ?? false);
10
+ const approvalsOf = (message)=>message?.role === 'assistant' ? message.parts.filter((p)=>'approval' === p.type) : [];
11
+ const hasPendingApproval = (message)=>approvalsOf(message).some((p)=>'pending' === p.status);
12
+ const getDockedApprovals = (lastRow)=>{
13
+ const approvals = approvalsOf(lastRow);
14
+ const pending = approvals.filter((p)=>'pending' === p.status);
15
+ if (pending.length) return pending;
16
+ const last = approvals[approvals.length - 1];
17
+ return last ? [
18
+ last
19
+ ] : NO_APPROVALS;
20
+ };
21
+ const copyTextOf = (message)=>'assistant' === message.role && message.copyText || message.parts.flatMap((p)=>'text' === p.type && p.text ? [
22
+ p.text
23
+ ] : []).join('\n\n');
24
+ const lastUserIdOf = (messages)=>{
25
+ for(let i = messages.length - 1; i >= 0; i--){
26
+ const m = messages[i];
27
+ if (m?.role === 'user') return m.id;
28
+ }
29
+ };
30
+ function deriveChatState(messages, status = 'ready', approvalPlacement = 'inline') {
31
+ const running = isRunningStatus(status);
32
+ const lastUserMessageId = lastUserIdOf(messages);
33
+ const last = messages[messages.length - 1];
34
+ const rows = running && last?.role === 'user' ? [
35
+ ...messages,
36
+ {
37
+ role: 'assistant',
38
+ id: `${last.id}:reply`,
39
+ parts: []
40
+ }
41
+ ] : messages;
42
+ const lastRow = rows[rows.length - 1];
43
+ const awaitingApproval = hasPendingApproval(lastRow);
44
+ return {
45
+ rows,
46
+ empty: 0 === messages.length,
47
+ running,
48
+ awaitingApproval,
49
+ busy: running && !awaitingApproval,
50
+ lastUserMessageId,
51
+ dockedApprovals: 'docked' === approvalPlacement ? getDockedApprovals(lastRow) : NO_APPROVALS
52
+ };
53
+ }
54
+ export { copyTextOf, deriveChatState, getDockedApprovals, hasPendingApproval, isLiveStep, isLiveStepStatus, isRunningStatus };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Every user-visible string WallyAssistant and the data views render. English defaults; pass a
3
+ * `Partial<ChatLabels>` to override, so a key added in a minor release doesn't break the build.
4
+ */
5
+ export interface ChatLabels {
6
+ /** Header title text; undefined keeps the built "Ask Wally" mark. */
7
+ title?: string;
8
+ /** Chat aria-label. */
9
+ region: string;
10
+ /** Log aria-label. */
11
+ log: string;
12
+ greeting: string;
13
+ suggestions: string;
14
+ placeholder: string;
15
+ /** Textarea aria-label. */
16
+ input: string;
17
+ send: string;
18
+ stop: string;
19
+ disclaimer: string;
20
+ scrollToBottom: string;
21
+ you: string;
22
+ assistant: string;
23
+ showMore: string;
24
+ showLess: string;
25
+ /** The loader and the synthetic Working row. */
26
+ working: string;
27
+ messageActions: string;
28
+ copy: string;
29
+ feedbackPositive: string;
30
+ feedbackNegative: string;
31
+ retry: string;
32
+ approvalCaption: string;
33
+ approvalAllowAlways: string;
34
+ approvalAllowOnce: string;
35
+ approvalReject: string;
36
+ approvalMoreOptions: string;
37
+ approved: string;
38
+ rejected: string;
39
+ permissions: string;
40
+ permissionsHeading: string;
41
+ removeContext: (label: string) => string;
42
+ }
43
+ export declare const DEFAULT_CHAT_LABELS: ChatLabels;
@@ -0,0 +1,33 @@
1
+ const DEFAULT_CHAT_LABELS = {
2
+ region: 'Wally chat',
3
+ log: 'Chat messages',
4
+ greeting: 'How can I help you today?',
5
+ suggestions: 'Suggestions',
6
+ placeholder: 'Ask Wally...',
7
+ input: 'Message Wally',
8
+ send: 'Send',
9
+ stop: 'Stop response',
10
+ disclaimer: 'Wally can make mistakes; always verify.',
11
+ scrollToBottom: 'Scroll to latest message',
12
+ you: 'You',
13
+ assistant: 'Wally',
14
+ showMore: 'Show more',
15
+ showLess: 'Show less',
16
+ working: 'Working...',
17
+ messageActions: 'Message actions',
18
+ copy: 'Copy',
19
+ feedbackPositive: 'Good response',
20
+ feedbackNegative: 'Bad response',
21
+ retry: 'Retry',
22
+ approvalCaption: 'Requires your approval',
23
+ approvalAllowAlways: 'Always allow in this session',
24
+ approvalAllowOnce: 'Allow once',
25
+ approvalReject: 'Reject',
26
+ approvalMoreOptions: 'More approval options',
27
+ approved: 'Approved',
28
+ rejected: 'Rejected',
29
+ permissions: 'Permission settings',
30
+ permissionsHeading: 'Always allowed in this conversation',
31
+ removeContext: (label)=>`Remove ${label}`
32
+ };
33
+ export { DEFAULT_CHAT_LABELS };
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Wally chat data model, owned by the design system and independent of CopilotKit, AG-UI and the AI SDK.
3
+ * The app writes one pure mapper (its API → these types); WallyAssistant renders the result, streaming included.
4
+ *
5
+ * Rules (mapper obligations: spec §7.2)
6
+ * - Plain data: no ReactNode, functions, Date or class instances. Times are ISO 8601 strings. `meta` and
7
+ * custom `data` are opaque to the DS (never read, rendered or serialized) and should stay JSON-serializable.
8
+ * - Every message, part, step and option has an `id` that never changes across snapshots.
9
+ * - Snapshots are immutable: pass new arrays and objects on change; keep unchanged nodes by identity where you can.
10
+ * - Empty strings and empty arrays mean "absent".
11
+ * - Renderers never throw on an unknown type, status, kind or icon value. New union members arrive in
12
+ * minor releases, so every `switch` over a DS union needs a `default` branch.
13
+ *
14
+ * Identity rules
15
+ * 1. A text part's `id` is fixed when it starts; its `text` grows.
16
+ * 2. A turn's id is `${userMessageId}:reply`, stable from the loading row through the answer or an error.
17
+ * Backend ids go in `meta` (e.g. `meta.sourceIds`).
18
+ * 3. A run that fails before any output is an assistant message with only an `error` part.
19
+ * 4. Optimistic user messages keep their client id after the server echoes them.
20
+ * 5. Step ids are unique within a message, so step toggles survive the stream.
21
+ * 6. Steps that arrive after a text part open a new chain-of-thought part; approvals don't close a block.
22
+ * One merged block followed by one text part is also valid.
23
+ * 7. Keep unchanged messages and parts by identity where you can; correctness doesn't depend on it.
24
+ * 8. On a thread switch, remount with `key={threadId}`.
25
+ */
26
+ export type ChatId = string;
27
+ /** Opaque app data, e.g. backend ids for feedback calls. */
28
+ export type ChatMeta = Readonly<Record<string, unknown>>;
29
+ /** Open vocabulary: known literals autocomplete, any other string still type-checks. */
30
+ export type ChatOpen<T extends string> = T | (string & {});
31
+ /** Same literals as AI SDK `ChatStatus`. 'error' behaves like 'ready'; the failure itself is an `error` part. */
32
+ export type ChatStatus = 'ready' | 'submitted' | 'streaming' | 'error';
33
+ /** Figma 483:1899 step types (resolved to src/icons inside the DS), or any key from the `icons` prop. */
34
+ export type ChatIconKey = ChatOpen<'thinking' | 'plan' | 'decision' | 'subagent' | 'tool' | 'command' | 'web-search' | 'query' | 'datastore' | 'api' | 'read' | 'fetch' | 'filter' | 'create' | 'edit' | 'cite' | 'threat' | 'scan' | 'pending' | 'summary' | 'created'>;
35
+ interface ChatPartBase {
36
+ readonly id: ChatId;
37
+ readonly meta?: ChatMeta;
38
+ }
39
+ /** Assistant text is GFM markdown, rendered by `markdown` (default `AssistantMessageMarkdown`); user text is plain, whitespace kept.
40
+ * While streaming, `text` grows under the same `id`: snapshots, never deltas. */
41
+ export interface ChatTextPart extends ChatPartBase {
42
+ readonly type: 'text';
43
+ readonly text: string;
44
+ }
45
+ /** A superset of AI SDK tool states, CopilotKit ToolCallStatus and AG-UI events:
46
+ * pending = args streaming · running = executing · awaiting-approval = waiting for a human ·
47
+ * done = has a result · error = failed · denied = the user rejected it · cancelled = the run stopped first. */
48
+ export type ChatStepStatus = 'pending' | 'running' | 'awaiting-approval' | 'done' | 'error' | 'denied' | 'cancelled';
49
+ /** Changes defaults only: reasoning → Brain icon, open while live; tool → Wrench; agent → Bot. */
50
+ export type ChatStepKind = ChatOpen<'reasoning' | 'tool' | 'agent'>;
51
+ /** One chain-of-thought row (Figma chain-item 201:1660). Recursive for sub-agents and grouped calls. */
52
+ export interface ChatStep {
53
+ readonly id: ChatId;
54
+ readonly status: ChatStepStatus;
55
+ /** Localized row text: "Thinking...", "Thought for 5s", "Searched for ABC". */
56
+ readonly label: string;
57
+ readonly kind?: ChatStepKind;
58
+ /** Machine name of the tool or agent ('propose_add_to_denylist'). Never rendered; for `renderStepContent`. */
59
+ readonly name?: string;
60
+ /** `null` = Figma "Simple" row (no icon cell, no connector). Absent = the kind's default. */
61
+ readonly icon?: ChatIconKey | null;
62
+ /** Right-aligned mono result (Figma "Simple-result"), e.g. "1,204". */
63
+ readonly metric?: string;
64
+ /** Collapsible body, markdown: reasoning text, tool output, error detail. Grows while the step is live.
65
+ * Rendered before `steps`. */
66
+ readonly content?: string;
67
+ /** Nested steps. For an ordered sub-agent log (text, step, text), put the text in child steps with `icon: null`.
68
+ * A sub-agent's own text never goes into the answer. */
69
+ readonly steps?: readonly ChatStep[];
70
+ readonly meta?: ChatMeta;
71
+ }
72
+ /** One block of steps, rendered as one ChainOfThought. */
73
+ export interface ChatChainOfThoughtPart extends ChatPartBase {
74
+ readonly type: 'chain-of-thought';
75
+ readonly steps: readonly ChatStep[];
76
+ /** "Worked for 3m 45s", or "Thought for 12s" for reasoning-only runs. When set, the block folds under this
77
+ * row once the run is over (§7.3). Leave it out to keep the block flat (e.g. a single reasoning step). */
78
+ readonly summary?: string;
79
+ }
80
+ /** Same literals as the built `ApprovalCardStatus`. */
81
+ export type ChatApprovalStatus = 'pending' | 'approved' | 'rejected';
82
+ /** Figma 182:4099: the first non-reject option is the primary button; other non-reject options go into its
83
+ * SplitButton menu; 'reject' options are secondary buttons. Unknown kinds count as allow. */
84
+ export type ChatApprovalOptionKind = ChatOpen<'allow-always' | 'allow-once' | 'reject'>;
85
+ export interface ChatApprovalOption {
86
+ readonly id: ChatId;
87
+ readonly kind: ChatApprovalOptionKind;
88
+ /** Localized button or menu text. */
89
+ readonly label: string;
90
+ }
91
+ /** Human-in-the-loop request (tool approval or interrupt). The answer leaves through `onApprovalRespond`;
92
+ * the new status arrives in the next snapshot — the DS keeps no optimistic state. */
93
+ export interface ChatApprovalPart extends ChatPartBase {
94
+ readonly type: 'approval';
95
+ readonly status: ChatApprovalStatus;
96
+ /** What Wally wants to do, markdown: inline code, a fenced args block (Figma 171:1790). */
97
+ readonly content: string;
98
+ /** Default: allow-always, allow-once, reject, with ChatLabels texts (Figma 182:4099). */
99
+ readonly options?: readonly ChatApprovalOption[];
100
+ /** Disables the buttons: the answer can't be sent yet, or one is in flight. */
101
+ readonly disabled?: boolean;
102
+ /** Replaces "Approved"/"Rejected" in the resolved row, e.g. "Expired" with status 'rejected'. */
103
+ readonly resolvedLabel?: string;
104
+ }
105
+ /** A failure shown inside an answer. A run that fails before any output is an assistant message with only this part. */
106
+ export interface ChatErrorPart extends ChatPartBase {
107
+ readonly type: 'error';
108
+ /** Localized plain text. */
109
+ readonly text: string;
110
+ /** Shows Retry when `onRetry` is set. */
111
+ readonly retryable?: boolean;
112
+ }
113
+ /** App-defined generative UI, rendered only by `renderPart`. Type your payload: `ChatCustomPart<AttackChart>`. */
114
+ export interface ChatCustomPart<D = unknown> extends ChatPartBase {
115
+ readonly type: 'custom';
116
+ /** Namespaced by convention: 'wallarm.attack-chart'. */
117
+ readonly kind: string;
118
+ readonly data: D;
119
+ }
120
+ export type ChatUserPart = ChatTextPart | ChatCustomPart;
121
+ export type ChatAssistantPart = ChatTextPart | ChatChainOfThoughtPart | ChatApprovalPart | ChatErrorPart | ChatCustomPart;
122
+ export type ChatPart = ChatUserPart | ChatAssistantPart;
123
+ interface ChatMessageBase {
124
+ readonly id: ChatId;
125
+ /** ISO 8601 → `<time dateTime>`, text from `formatTimestamp`. */
126
+ readonly createdAt?: string;
127
+ readonly meta?: ChatMeta;
128
+ }
129
+ export interface ChatUserMessage extends ChatMessageBase {
130
+ readonly role: 'user';
131
+ readonly parts: readonly ChatUserPart[];
132
+ }
133
+ export type ChatFeedback = 'positive' | 'negative';
134
+ /** One assistant turn: the mapper folds the turn's reasoning, tool and text source messages into it. */
135
+ export interface ChatAssistantMessage extends ChatMessageBase {
136
+ readonly role: 'assistant';
137
+ readonly parts: readonly ChatAssistantPart[];
138
+ /** App-owned current feedback; null or absent = none. */
139
+ readonly feedback?: ChatFeedback | null;
140
+ /** What Copy copies. Default: the text parts joined by a blank line. */
141
+ readonly copyText?: string;
142
+ }
143
+ export type ChatMessage = ChatUserMessage | ChatAssistantMessage;
144
+ export interface ChatSuggestionItem {
145
+ readonly id: ChatId;
146
+ /** Pill text. */
147
+ readonly label: string;
148
+ /** Sent on click; default `label`. */
149
+ readonly prompt?: string;
150
+ readonly meta?: ChatMeta;
151
+ }
152
+ /** One "Always allowed in this conversation" switch row. */
153
+ export interface ChatToolPermission {
154
+ readonly id: ChatId;
155
+ /** Tool name, e.g. 'propose_add_to_denylist'. */
156
+ readonly title: string;
157
+ readonly description?: string;
158
+ readonly allowed: boolean;
159
+ }
160
+ /** A context chip in the input bar (Figma 26:656 / 26:657). */
161
+ export interface ChatContextItem {
162
+ readonly id: ChatId;
163
+ readonly label: string;
164
+ /** Default: Quote. */
165
+ readonly icon?: ChatIconKey;
166
+ /** Default true; removing needs `onContextRemove`. */
167
+ readonly removable?: boolean;
168
+ }
169
+ export interface ChatApprovalResponse {
170
+ readonly approvalId: ChatId;
171
+ readonly optionId: ChatId;
172
+ readonly kind: ChatApprovalOptionKind;
173
+ /** `kind !== 'reject'`. */
174
+ readonly approved: boolean;
175
+ }
176
+ /** What a mapper returns; it spreads straight into <WallyAssistant {...snapshot} />. */
177
+ export interface ChatSnapshot {
178
+ readonly messages: readonly ChatMessage[];
179
+ readonly status: ChatStatus;
180
+ readonly suggestions?: readonly ChatSuggestionItem[];
181
+ readonly permissions?: readonly ChatToolPermission[];
182
+ readonly context?: readonly ChatContextItem[];
183
+ }
184
+ export {};
File without changes
@@ -0,0 +1,20 @@
1
+ import type { FC, ReactNode } from 'react';
2
+ import { type ApprovalCardProps } from '../../ApprovalCard/index.js';
3
+ import type { ChatApprovalPart, ChatApprovalResponse, ChatMessage } from '../model/model.js';
4
+ export interface ApprovalCardViewProps extends Omit<ApprovalCardProps, 'status' | 'children' | 'caption' | 'approvedLabel' | 'rejectedLabel'> {
5
+ approval: ChatApprovalPart;
6
+ message?: ChatMessage;
7
+ /** Default: the provider's onApprovalRespond. Absent → buttons disabled. */
8
+ onRespond?: (response: ChatApprovalResponse) => void;
9
+ /** ORed with `approval.disabled`; ChatPartView sets it for approvals in older messages. */
10
+ disabled?: boolean;
11
+ /** Replaces the default option buttons: render your own ApprovalCardActions (the analytics seam).
12
+ * undefined = the defaults; null = no actions. */
13
+ children?: ReactNode;
14
+ }
15
+ /**
16
+ * One `approval` part as an `ApprovalCard`: the caption, `content` through `markdown`, then the
17
+ * default option buttons (or your `children`). The answer leaves through `onRespond` or the
18
+ * provider's `onApprovalRespond`; the resolved status arrives in the next snapshot.
19
+ */
20
+ export declare const ApprovalCardView: FC<ApprovalCardViewProps>;
@@ -0,0 +1,274 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { ChevronDown } from "../../../icons/index.js";
4
+ import { useTestId } from "../../../utils/testId.js";
5
+ import { ApprovalCard, ApprovalCardActions, ApprovalCardContent } from "../../ApprovalCard/index.js";
6
+ import { Button } from "../../Button/index.js";
7
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../DropdownMenu/index.js";
8
+ import { SplitButton } from "../../SplitButton/index.js";
9
+ import { MarkdownView, useChatView } from "./ChatViewContext.js";
10
+ const defaultOptions = (labels)=>[
11
+ {
12
+ id: "allow-always",
13
+ kind: "allow-always",
14
+ label: labels.approvalAllowAlways
15
+ },
16
+ {
17
+ id: "allow-once",
18
+ kind: "allow-once",
19
+ label: labels.approvalAllowOnce
20
+ },
21
+ {
22
+ id: "reject",
23
+ kind: "reject",
24
+ label: labels.approvalReject
25
+ }
26
+ ];
27
+ const MENU_POSITIONING = {
28
+ placement: "bottom-end"
29
+ };
30
+ const DefaultActions = (t0)=>{
31
+ const $ = c(37);
32
+ const { options, disabled, moreLabel, onSelect } = t0;
33
+ const base = useTestId();
34
+ let t1;
35
+ if ($[0] !== base) {
36
+ t1 = (slot)=>base ? `${base}--${slot}` : void 0;
37
+ $[0] = base;
38
+ $[1] = t1;
39
+ } else t1 = $[1];
40
+ const idOf = t1;
41
+ let t2;
42
+ if ($[2] !== options) {
43
+ t2 = options.filter(_temp);
44
+ $[2] = options;
45
+ $[3] = t2;
46
+ } else t2 = $[3];
47
+ let more;
48
+ let primary;
49
+ if ($[4] !== t2) {
50
+ [primary, ...more] = t2;
51
+ $[4] = t2;
52
+ $[5] = more;
53
+ $[6] = primary;
54
+ } else {
55
+ more = $[5];
56
+ primary = $[6];
57
+ }
58
+ let T0;
59
+ let t3;
60
+ let t4;
61
+ if ($[7] !== disabled || $[8] !== idOf || $[9] !== more || $[10] !== moreLabel || $[11] !== onSelect || $[12] !== options || $[13] !== primary) {
62
+ const rejects = options.filter(_temp2);
63
+ let t5;
64
+ if ($[17] !== disabled || $[18] !== idOf || $[19] !== onSelect || $[20] !== primary) {
65
+ t5 = primary && /*#__PURE__*/ jsx(Button, {
66
+ disabled: disabled,
67
+ "data-testid": idOf(`option-${primary.id}`),
68
+ onClick: ()=>onSelect(primary),
69
+ children: primary.label
70
+ });
71
+ $[17] = disabled;
72
+ $[18] = idOf;
73
+ $[19] = onSelect;
74
+ $[20] = primary;
75
+ $[21] = t5;
76
+ } else t5 = $[21];
77
+ const primaryButton = t5;
78
+ T0 = ApprovalCardActions;
79
+ if ($[22] !== disabled || $[23] !== idOf || $[24] !== more || $[25] !== moreLabel || $[26] !== onSelect || $[27] !== primaryButton) {
80
+ t3 = more.length ? /*#__PURE__*/ jsxs(DropdownMenu, {
81
+ positioning: MENU_POSITIONING,
82
+ children: [
83
+ /*#__PURE__*/ jsxs(SplitButton, {
84
+ children: [
85
+ primaryButton,
86
+ /*#__PURE__*/ jsx(DropdownMenuTrigger, {
87
+ asChild: true,
88
+ "data-testid": idOf("more"),
89
+ children: /*#__PURE__*/ jsx(Button, {
90
+ "aria-label": moreLabel,
91
+ disabled: disabled,
92
+ children: /*#__PURE__*/ jsx(ChevronDown, {})
93
+ })
94
+ })
95
+ ]
96
+ }),
97
+ /*#__PURE__*/ jsx(DropdownMenuContent, {
98
+ children: more.map((option)=>/*#__PURE__*/ jsx(DropdownMenuItem, {
99
+ disabled: disabled,
100
+ "data-testid": idOf(`option-${option.id}`),
101
+ onSelect: ()=>onSelect(option),
102
+ children: option.label
103
+ }, option.id))
104
+ })
105
+ ]
106
+ }) : primaryButton;
107
+ $[22] = disabled;
108
+ $[23] = idOf;
109
+ $[24] = more;
110
+ $[25] = moreLabel;
111
+ $[26] = onSelect;
112
+ $[27] = primaryButton;
113
+ $[28] = t3;
114
+ } else t3 = $[28];
115
+ let t6;
116
+ if ($[29] !== disabled || $[30] !== idOf || $[31] !== onSelect) {
117
+ t6 = (option_0)=>/*#__PURE__*/ jsx(Button, {
118
+ variant: "secondary",
119
+ color: "neutral",
120
+ disabled: disabled,
121
+ "data-testid": idOf(`option-${option_0.id}`),
122
+ onClick: ()=>onSelect(option_0),
123
+ children: option_0.label
124
+ }, option_0.id);
125
+ $[29] = disabled;
126
+ $[30] = idOf;
127
+ $[31] = onSelect;
128
+ $[32] = t6;
129
+ } else t6 = $[32];
130
+ t4 = rejects.map(t6);
131
+ $[7] = disabled;
132
+ $[8] = idOf;
133
+ $[9] = more;
134
+ $[10] = moreLabel;
135
+ $[11] = onSelect;
136
+ $[12] = options;
137
+ $[13] = primary;
138
+ $[14] = T0;
139
+ $[15] = t3;
140
+ $[16] = t4;
141
+ } else {
142
+ T0 = $[14];
143
+ t3 = $[15];
144
+ t4 = $[16];
145
+ }
146
+ let t5;
147
+ if ($[33] !== T0 || $[34] !== t3 || $[35] !== t4) {
148
+ t5 = /*#__PURE__*/ jsxs(T0, {
149
+ children: [
150
+ t3,
151
+ t4
152
+ ]
153
+ });
154
+ $[33] = T0;
155
+ $[34] = t3;
156
+ $[35] = t4;
157
+ $[36] = t5;
158
+ } else t5 = $[36];
159
+ return t5;
160
+ };
161
+ const ApprovalCardView = (t0)=>{
162
+ const $ = c(31);
163
+ let approval;
164
+ let children;
165
+ let message;
166
+ let onRespond;
167
+ let props;
168
+ let t1;
169
+ if ($[0] !== t0) {
170
+ ({ approval, message, onRespond, disabled: t1, children, ...props } = t0);
171
+ $[0] = t0;
172
+ $[1] = approval;
173
+ $[2] = children;
174
+ $[3] = message;
175
+ $[4] = onRespond;
176
+ $[5] = props;
177
+ $[6] = t1;
178
+ } else {
179
+ approval = $[1];
180
+ children = $[2];
181
+ message = $[3];
182
+ onRespond = $[4];
183
+ props = $[5];
184
+ t1 = $[6];
185
+ }
186
+ const disabled = void 0 === t1 ? false : t1;
187
+ const { labels, handlers, hasApprovalRespond } = useChatView();
188
+ const canRespond = null != onRespond || hasApprovalRespond;
189
+ let t2;
190
+ if ($[7] !== approval || $[8] !== handlers || $[9] !== onRespond) {
191
+ t2 = (option)=>{
192
+ const response = {
193
+ approvalId: approval.id,
194
+ optionId: option.id,
195
+ kind: option.kind,
196
+ approved: "reject" !== option.kind
197
+ };
198
+ if (onRespond) onRespond(response);
199
+ else handlers.current.onApprovalRespond?.(response, approval);
200
+ };
201
+ $[7] = approval;
202
+ $[8] = handlers;
203
+ $[9] = onRespond;
204
+ $[10] = t2;
205
+ } else t2 = $[10];
206
+ const respond = t2;
207
+ const t3 = approval.resolvedLabel || labels.approved;
208
+ const t4 = approval.resolvedLabel || labels.rejected;
209
+ const t5 = message?.id;
210
+ let t6;
211
+ if ($[11] !== approval.content || $[12] !== approval.id || $[13] !== t5) {
212
+ t6 = /*#__PURE__*/ jsx(ApprovalCardContent, {
213
+ children: /*#__PURE__*/ jsx(MarkdownView, {
214
+ text: approval.content,
215
+ streaming: false,
216
+ variant: "approval",
217
+ messageId: t5,
218
+ partId: approval.id
219
+ })
220
+ });
221
+ $[11] = approval.content;
222
+ $[12] = approval.id;
223
+ $[13] = t5;
224
+ $[14] = t6;
225
+ } else t6 = $[14];
226
+ let t7;
227
+ if ($[15] !== approval.disabled || $[16] !== approval.options || $[17] !== canRespond || $[18] !== children || $[19] !== disabled || $[20] !== labels || $[21] !== respond) {
228
+ t7 = void 0 !== children ? children : /*#__PURE__*/ jsx(DefaultActions, {
229
+ options: approval.options?.length ? approval.options : defaultOptions(labels),
230
+ disabled: disabled || !!approval.disabled || !canRespond,
231
+ moreLabel: labels.approvalMoreOptions,
232
+ onSelect: respond
233
+ });
234
+ $[15] = approval.disabled;
235
+ $[16] = approval.options;
236
+ $[17] = canRespond;
237
+ $[18] = children;
238
+ $[19] = disabled;
239
+ $[20] = labels;
240
+ $[21] = respond;
241
+ $[22] = t7;
242
+ } else t7 = $[22];
243
+ let t8;
244
+ if ($[23] !== approval.status || $[24] !== labels.approvalCaption || $[25] !== props || $[26] !== t3 || $[27] !== t4 || $[28] !== t6 || $[29] !== t7) {
245
+ t8 = /*#__PURE__*/ jsxs(ApprovalCard, {
246
+ ...props,
247
+ status: approval.status,
248
+ caption: labels.approvalCaption,
249
+ approvedLabel: t3,
250
+ rejectedLabel: t4,
251
+ children: [
252
+ t6,
253
+ t7
254
+ ]
255
+ });
256
+ $[23] = approval.status;
257
+ $[24] = labels.approvalCaption;
258
+ $[25] = props;
259
+ $[26] = t3;
260
+ $[27] = t4;
261
+ $[28] = t6;
262
+ $[29] = t7;
263
+ $[30] = t8;
264
+ } else t8 = $[30];
265
+ return t8;
266
+ };
267
+ ApprovalCardView.displayName = "ApprovalCardView";
268
+ function _temp(o) {
269
+ return "reject" !== o.kind;
270
+ }
271
+ function _temp2(o_0) {
272
+ return "reject" === o_0.kind;
273
+ }
274
+ export { ApprovalCardView };
@@ -0,0 +1,18 @@
1
+ import { type FC } from 'react';
2
+ import { type ChainOfThoughtProps } from '../../ChainOfThought/index.js';
3
+ import type { ChatChainOfThoughtPart, ChatMessage } from '../model/model.js';
4
+ /** `...rest` lands on the root `ol`. The DOM `part` attribute is dropped: `part` is the data here. */
5
+ export interface ChainOfThoughtViewProps extends Omit<ChainOfThoughtProps, 'children' | 'part'> {
6
+ part: ChatChainOfThoughtPart;
7
+ message: ChatMessage;
8
+ /** The run is still producing this message: the block stays flat and never folds. */
9
+ active?: boolean;
10
+ /** Append the synthetic "Working..." row: the run is busy but no step is live. */
11
+ working?: boolean;
12
+ }
13
+ /**
14
+ * One `chain-of-thought` part as a `ChainOfThought`. Flat while the run is active (plus a
15
+ * "Working..." row when `working`); folds under its `summary` once the run is over. A reasoning
16
+ * step is open while live and closes when done; a manual toggle always wins and survives the fold.
17
+ */
18
+ export declare const ChainOfThoughtView: FC<ChainOfThoughtViewProps>;