@aleph-alpha/chat-kit 3.2.0 → 4.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.
Files changed (164) hide show
  1. package/dist/{CkInput.vue_vue_type_script_setup_true_lang-B-4xnH2c.js → CkInput.vue_vue_type_script_setup_true_lang-DJN-nZ2-.js} +391 -113
  2. package/dist/adapters/responses-api.d.ts +11 -5
  3. package/dist/adapters/responses-api.d.ts.map +1 -1
  4. package/dist/adapters/responses-api.js +9 -3
  5. package/dist/chat-kit.css +14 -8
  6. package/dist/components/base/CkAgentMessage/CkAgentMessage.stories.d.ts +7 -0
  7. package/dist/components/base/CkAgentMessage/CkAgentMessage.stories.d.ts.map +1 -1
  8. package/dist/components/base/CkAgentMessage/types.d.ts +1 -1
  9. package/dist/components/base/CkCitation/CkCitation.stories.d.ts +47 -0
  10. package/dist/components/base/CkCitation/CkCitation.stories.d.ts.map +1 -0
  11. package/dist/components/base/CkCitation/CkCitation.vue.d.ts +15 -0
  12. package/dist/components/base/CkCitation/CkCitation.vue.d.ts.map +1 -0
  13. package/dist/components/base/CkCitation/index.d.ts +3 -0
  14. package/dist/components/base/CkCitation/index.d.ts.map +1 -0
  15. package/dist/components/base/CkCitation/types.d.ts +79 -0
  16. package/dist/components/base/CkCitation/types.d.ts.map +1 -0
  17. package/dist/components/base/CkCitationCard/CkCitationCard.stories.d.ts +51 -0
  18. package/dist/components/base/CkCitationCard/CkCitationCard.stories.d.ts.map +1 -0
  19. package/dist/components/base/CkCitationCard/CkCitationCard.vue.d.ts +13 -0
  20. package/dist/components/base/CkCitationCard/CkCitationCard.vue.d.ts.map +1 -0
  21. package/dist/components/base/CkCitationCard/index.d.ts +3 -0
  22. package/dist/components/base/CkCitationCard/index.d.ts.map +1 -0
  23. package/dist/components/base/CkCitationCard/types.d.ts +51 -0
  24. package/dist/components/base/CkCitationCard/types.d.ts.map +1 -0
  25. package/dist/components/base/{CkCopyMessageActionButton/CkCopyMessageActionButton.stories.d.ts → CkCopyMessageButton/CkCopyMessageButton.stories.d.ts} +3 -3
  26. package/dist/components/base/CkCopyMessageButton/CkCopyMessageButton.stories.d.ts.map +1 -0
  27. package/dist/components/base/{CkCopyMessageActionButton/CkCopyMessageActionButton.vue.d.ts → CkCopyMessageButton/CkCopyMessageButton.vue.d.ts} +4 -4
  28. package/dist/components/base/CkCopyMessageButton/CkCopyMessageButton.vue.d.ts.map +1 -0
  29. package/dist/components/base/CkCopyMessageButton/index.d.ts +3 -0
  30. package/dist/components/base/CkCopyMessageButton/index.d.ts.map +1 -0
  31. package/dist/components/base/{CkCopyMessageActionButton → CkCopyMessageButton}/types.d.ts +3 -3
  32. package/dist/components/base/CkCopyMessageButton/types.d.ts.map +1 -0
  33. package/dist/components/base/CkDropZoneOverlay/CkDropZoneOverlay.vue.d.ts +1 -1
  34. package/dist/components/base/CkFeedbackButton/types.d.ts +1 -1
  35. package/dist/components/base/CkFeedbackDialog/CkFeedbackDialog.vue.d.ts +2 -2
  36. package/dist/components/base/CkFeedbackDialog/types.d.ts +1 -1
  37. package/dist/components/base/CkFileItemsList/CkFileItemsList.vue.d.ts +1 -1
  38. package/dist/components/base/CkMarkdownRenderer/CkMarkdownRenderer.stories.d.ts +15 -0
  39. package/dist/components/base/CkMarkdownRenderer/CkMarkdownRenderer.stories.d.ts.map +1 -1
  40. package/dist/components/base/CkMarkdownRenderer/CkMarkdownRenderer.vue.d.ts +16 -2
  41. package/dist/components/base/CkMarkdownRenderer/CkMarkdownRenderer.vue.d.ts.map +1 -1
  42. package/dist/components/base/CkMarkdownRenderer/index.d.ts +1 -1
  43. package/dist/components/base/CkMarkdownRenderer/index.d.ts.map +1 -1
  44. package/dist/components/base/CkMarkdownRenderer/types.d.ts +25 -0
  45. package/dist/components/base/CkMarkdownRenderer/types.d.ts.map +1 -1
  46. package/dist/components/base/CkMarkdownRenderer/useCitationRendering.d.ts +17 -0
  47. package/dist/components/base/CkMarkdownRenderer/useCitationRendering.d.ts.map +1 -0
  48. package/dist/components/base/{CkMessageActionButton/CkMessageActionButton.stories.d.ts → CkMessageButton/CkMessageButton.stories.d.ts} +3 -3
  49. package/dist/components/base/CkMessageButton/CkMessageButton.stories.d.ts.map +1 -0
  50. package/dist/components/base/{CkMessageActionButton/CkMessageActionButton.vue.d.ts → CkMessageButton/CkMessageButton.vue.d.ts} +3 -3
  51. package/dist/components/base/CkMessageButton/CkMessageButton.vue.d.ts.map +1 -0
  52. package/dist/components/base/CkMessageButton/index.d.ts +3 -0
  53. package/dist/components/base/CkMessageButton/index.d.ts.map +1 -0
  54. package/dist/components/base/{CkMessageActionButton → CkMessageButton}/types.d.ts +2 -2
  55. package/dist/components/base/CkMessageButton/types.d.ts.map +1 -0
  56. package/dist/components/base/CkPromptSendButton/CkPromptSendButton.vue.d.ts +1 -1
  57. package/dist/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.stories.d.ts +16 -0
  58. package/dist/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.stories.d.ts.map +1 -0
  59. package/dist/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.vue.d.ts +12 -0
  60. package/dist/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.vue.d.ts.map +1 -0
  61. package/dist/components/base/CkRegenerateMessageButton/index.d.ts +3 -0
  62. package/dist/components/base/{CkCopyMessageActionButton → CkRegenerateMessageButton}/index.d.ts.map +1 -1
  63. package/dist/components/base/CkRegenerateMessageButton/types.d.ts +27 -0
  64. package/dist/components/base/CkRegenerateMessageButton/types.d.ts.map +1 -0
  65. package/dist/components/base/index.d.ts +8 -3
  66. package/dist/components/base/index.d.ts.map +1 -1
  67. package/dist/components/composed/CkConversation/CkConversation.stories.d.ts +1 -1
  68. package/dist/components/composed/CkConversation/types.d.ts +1 -1
  69. package/dist/components/composed/CkInput/CkInput.vue.d.ts +1 -1
  70. package/dist/components/index.d.ts +2 -2
  71. package/dist/components/index.d.ts.map +1 -1
  72. package/dist/components/index.js +26 -23
  73. package/dist/composables/fileUpload/useFileUpload.d.ts.map +1 -1
  74. package/dist/composables/fileUpload/useFileUploadWrapper.d.ts.map +1 -1
  75. package/dist/composables/index.js +1 -1
  76. package/dist/handlers/index.d.ts +2 -0
  77. package/dist/handlers/index.d.ts.map +1 -1
  78. package/dist/handlers/index.js +4 -3
  79. package/dist/handlers/useChatKitLabels.d.ts +13 -0
  80. package/dist/handlers/useChatKitLabels.d.ts.map +1 -1
  81. package/dist/handlers/useMarkdownParser.d.ts.map +1 -1
  82. package/dist/handlers/useMessageHandler.d.ts +37 -0
  83. package/dist/handlers/useMessageHandler.d.ts.map +1 -1
  84. package/dist/helpers/conversationTree.d.ts +15 -0
  85. package/dist/helpers/conversationTree.d.ts.map +1 -1
  86. package/dist/helpers/unified/remarkCitations.d.ts +17 -0
  87. package/dist/helpers/unified/remarkCitations.d.ts.map +1 -0
  88. package/dist/{index-DAmWGYNH.js → index-CyrVnbS9.js} +86 -71
  89. package/dist/index.d.ts +2 -2
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +30 -27
  92. package/dist/{useChatKitLabels-D5gNv8se.js → useChatKitLabels-zMFV7aEz.js} +31 -3
  93. package/dist/{useMessageHandler-CMdy-lm0.js → useMessageHandler-N50Yj-NU.js} +45 -7
  94. package/package.json +5 -3
  95. package/src/adapters/responses-api.spec.ts +52 -5
  96. package/src/adapters/responses-api.ts +26 -7
  97. package/src/components/base/CkAgentMessage/CkAgentMessage.stories.ts +112 -0
  98. package/src/components/base/CkAgentMessage/types.ts +1 -1
  99. package/src/components/base/CkCitation/CkCitation.spec.ts +79 -0
  100. package/src/components/base/CkCitation/CkCitation.stories.ts +136 -0
  101. package/src/components/base/CkCitation/CkCitation.vue +145 -0
  102. package/src/components/base/CkCitation/index.ts +2 -0
  103. package/src/components/base/CkCitation/types.ts +80 -0
  104. package/src/components/base/CkCitationCard/CkCitationCard.spec.ts +77 -0
  105. package/src/components/base/CkCitationCard/CkCitationCard.stories.ts +144 -0
  106. package/src/components/base/CkCitationCard/CkCitationCard.vue +76 -0
  107. package/src/components/base/CkCitationCard/index.ts +2 -0
  108. package/src/components/base/CkCitationCard/types.ts +51 -0
  109. package/src/components/base/{CkCopyMessageActionButton/CkCopyMessageActionButton.spec.ts → CkCopyMessageButton/CkCopyMessageButton.spec.ts} +6 -6
  110. package/src/components/base/{CkCopyMessageActionButton/CkCopyMessageActionButton.stories.ts → CkCopyMessageButton/CkCopyMessageButton.stories.ts} +8 -8
  111. package/src/components/base/{CkCopyMessageActionButton/CkCopyMessageActionButton.vue → CkCopyMessageButton/CkCopyMessageButton.vue} +6 -6
  112. package/src/components/base/CkCopyMessageButton/index.ts +2 -0
  113. package/src/components/base/{CkCopyMessageActionButton → CkCopyMessageButton}/types.ts +3 -3
  114. package/src/components/base/CkFeedbackButton/CkFeedbackButton.vue +5 -5
  115. package/src/components/base/CkFeedbackButton/types.ts +1 -1
  116. package/src/components/base/CkFeedbackDialog/types.ts +1 -1
  117. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.spec.ts +124 -0
  118. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.stories.ts +118 -0
  119. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.vue +70 -28
  120. package/src/components/base/CkMarkdownRenderer/index.ts +1 -0
  121. package/src/components/base/CkMarkdownRenderer/types.ts +26 -0
  122. package/src/components/base/CkMarkdownRenderer/useCitationRendering.spec.ts +94 -0
  123. package/src/components/base/CkMarkdownRenderer/useCitationRendering.ts +52 -0
  124. package/src/components/base/{CkMessageActionButton/CkMessageActionButton.spec.ts → CkMessageButton/CkMessageButton.spec.ts} +6 -6
  125. package/src/components/base/{CkMessageActionButton/CkMessageActionButton.stories.ts → CkMessageButton/CkMessageButton.stories.ts} +10 -10
  126. package/src/components/base/{CkMessageActionButton/CkMessageActionButton.vue → CkMessageButton/CkMessageButton.vue} +3 -3
  127. package/src/components/base/CkMessageButton/index.ts +2 -0
  128. package/src/components/base/{CkMessageActionButton → CkMessageButton}/types.ts +2 -2
  129. package/src/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.spec.ts +49 -0
  130. package/src/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.stories.ts +63 -0
  131. package/src/components/base/CkRegenerateMessageButton/CkRegenerateMessageButton.vue +43 -0
  132. package/src/components/base/CkRegenerateMessageButton/index.ts +2 -0
  133. package/src/components/base/CkRegenerateMessageButton/types.ts +27 -0
  134. package/src/components/base/index.ts +15 -2
  135. package/src/components/composed/CkConversation/CkConversation.stories.ts +6 -6
  136. package/src/components/composed/CkConversation/CkConversation.vue +2 -2
  137. package/src/components/composed/CkConversation/types.ts +1 -1
  138. package/src/components/index.ts +11 -2
  139. package/src/composables/fileUpload/useFileUpload.spec.ts +2 -61
  140. package/src/composables/fileUpload/useFileUpload.ts +2 -9
  141. package/src/composables/fileUpload/useFileUploadWrapper.spec.ts +195 -14
  142. package/src/composables/fileUpload/useFileUploadWrapper.ts +114 -81
  143. package/src/handlers/index.ts +2 -0
  144. package/src/handlers/useChatKitLabels.spec.ts +1 -0
  145. package/src/handlers/useChatKitLabels.ts +16 -0
  146. package/src/handlers/useMarkdownParser.ts +5 -2
  147. package/src/handlers/useMessageHandler.spec.ts +79 -0
  148. package/src/handlers/useMessageHandler.ts +50 -2
  149. package/src/helpers/conversationTree.spec.ts +120 -0
  150. package/src/helpers/conversationTree.ts +57 -8
  151. package/src/helpers/unified/remarkCitations.spec.ts +112 -0
  152. package/src/helpers/unified/remarkCitations.ts +55 -0
  153. package/src/index.ts +11 -2
  154. package/dist/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.stories.d.ts.map +0 -1
  155. package/dist/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.vue.d.ts.map +0 -1
  156. package/dist/components/base/CkCopyMessageActionButton/index.d.ts +0 -3
  157. package/dist/components/base/CkCopyMessageActionButton/types.d.ts.map +0 -1
  158. package/dist/components/base/CkMessageActionButton/CkMessageActionButton.stories.d.ts.map +0 -1
  159. package/dist/components/base/CkMessageActionButton/CkMessageActionButton.vue.d.ts.map +0 -1
  160. package/dist/components/base/CkMessageActionButton/index.d.ts +0 -3
  161. package/dist/components/base/CkMessageActionButton/index.d.ts.map +0 -1
  162. package/dist/components/base/CkMessageActionButton/types.d.ts.map +0 -1
  163. package/src/components/base/CkCopyMessageActionButton/index.ts +0 -2
  164. package/src/components/base/CkMessageActionButton/index.ts +0 -2
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
- import type { CkMessageActionButtonProps } from './types';
2
+ import type { CkMessageButtonProps } from './types';
3
3
  import { UiButton } from '@aleph-alpha/ui-library';
4
4
 
5
5
  defineOptions({
6
- name: 'CkMessageActionButton',
6
+ name: 'CkMessageButton',
7
7
  });
8
8
 
9
- withDefaults(defineProps<CkMessageActionButtonProps>(), {
9
+ withDefaults(defineProps<CkMessageButtonProps>(), {
10
10
  disabled: false,
11
11
  });
12
12
  </script>
@@ -0,0 +1,2 @@
1
+ export { default as CkMessageButton } from './CkMessageButton.vue';
2
+ export type * from './types';
@@ -5,9 +5,9 @@
5
5
  * @category Actions
6
6
  * @useCases message footer action, like/dislike reaction, share button on reply, secondary message action
7
7
  * @keywords icon button, action, message, ghost, accessible, aria-label
8
- * @related CkCopyMessageActionButton, CkAgentMessage, CkConversation
8
+ * @related CkCopyMessageButton, CkAgentMessage, CkConversation
9
9
  */
10
- export interface CkMessageActionButtonProps {
10
+ export interface CkMessageButtonProps {
11
11
  /**
12
12
  * Accessible label for the button. **Required** because the button only
13
13
  * renders an icon.
@@ -0,0 +1,49 @@
1
+ import CkRegenerateMessageButton from './CkRegenerateMessageButton.vue';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { render, screen } from '@testing-library/vue';
4
+ import { describe, expect, it } from 'vitest';
5
+
6
+ describe('CkRegenerateMessageButton', () => {
7
+ it('renders an accessible button with the default label', () => {
8
+ render(CkRegenerateMessageButton);
9
+
10
+ expect(
11
+ screen.getByRole('button', { name: 'Regenerate response' }),
12
+ ).toBeInTheDocument();
13
+ });
14
+
15
+ it('uses a custom aria-label when provided', () => {
16
+ render(CkRegenerateMessageButton, {
17
+ props: { ariaLabel: 'Try again' },
18
+ });
19
+
20
+ expect(
21
+ screen.getByRole('button', { name: 'Try again' }),
22
+ ).toBeInTheDocument();
23
+ });
24
+
25
+ it('emits regenerate when clicked', async () => {
26
+ const user = userEvent.setup();
27
+ const { emitted } = render(CkRegenerateMessageButton);
28
+
29
+ await user.click(
30
+ screen.getByRole('button', { name: 'Regenerate response' }),
31
+ );
32
+
33
+ expect(emitted('regenerate')).toEqual([[]]);
34
+ });
35
+
36
+ it('does not emit regenerate when disabled', async () => {
37
+ const user = userEvent.setup();
38
+ const { emitted } = render(CkRegenerateMessageButton, {
39
+ props: { disabled: true },
40
+ });
41
+
42
+ const button = screen.getByRole('button', { name: 'Regenerate response' });
43
+ expect(button).toBeDisabled();
44
+
45
+ await user.click(button);
46
+
47
+ expect(emitted('regenerate')).toBeUndefined();
48
+ });
49
+ });
@@ -0,0 +1,63 @@
1
+ import CkRegenerateMessageButton from './CkRegenerateMessageButton.vue';
2
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
3
+
4
+ const meta: Meta<typeof CkRegenerateMessageButton> = {
5
+ title: 'Base/CkRegenerateMessageButton',
6
+ component: CkRegenerateMessageButton,
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ disabled: {
10
+ control: 'boolean',
11
+ description: 'Whether the button is disabled and ignores clicks.',
12
+ },
13
+ ariaLabel: {
14
+ control: 'text',
15
+ description: 'Accessible label and tooltip content for the button.',
16
+ },
17
+ },
18
+ decorators: [
19
+ () => ({
20
+ template:
21
+ '<div style="max-width: 640px; margin: 0 auto; padding: 24px;"><story /></div>',
22
+ }),
23
+ ],
24
+ };
25
+
26
+ export default meta;
27
+ type Story = StoryObj<typeof meta>;
28
+
29
+ const defaultTemplateSource = `<script setup lang="ts">
30
+ import { CkRegenerateMessageButton } from '@aleph-alpha/chat-kit';
31
+ </script>
32
+
33
+ <template>
34
+ <CkRegenerateMessageButton @regenerate="() => {}" />
35
+ </template>`;
36
+
37
+ const disabledTemplateSource = `<script setup lang="ts">
38
+ import { CkRegenerateMessageButton } from '@aleph-alpha/chat-kit';
39
+ </script>
40
+
41
+ <template>
42
+ <CkRegenerateMessageButton disabled />
43
+ </template>`;
44
+
45
+ /**
46
+ * Default regenerate action. Clicking emits a `regenerate` event so the host
47
+ * can request a new response for the message.
48
+ */
49
+ export const Default: Story = {
50
+ args: {},
51
+ parameters: { docs: { source: { code: defaultTemplateSource } } },
52
+ };
53
+
54
+ /**
55
+ * Disabled state — clicks are ignored and the button appears inactive.
56
+ * Use while a message is still streaming or in an error state.
57
+ */
58
+ export const Disabled: Story = {
59
+ args: {
60
+ disabled: true,
61
+ },
62
+ parameters: { docs: { source: { code: disabledTemplateSource } } },
63
+ };
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import { CkMessageButton } from '../CkMessageButton';
3
+ import type { CkRegenerateMessageButtonProps } from './types';
4
+ import { UiIcon, UiTooltip } from '@aleph-alpha/ui-library';
5
+
6
+ defineOptions({
7
+ name: 'CkRegenerateMessageButton',
8
+ });
9
+
10
+ const props = withDefaults(defineProps<CkRegenerateMessageButtonProps>(), {
11
+ disabled: false,
12
+ ariaLabel: 'Regenerate response',
13
+ });
14
+
15
+ const emit = defineEmits<{
16
+ regenerate: [];
17
+ }>();
18
+
19
+ function handleClick() {
20
+ if (props.disabled) {
21
+ return;
22
+ }
23
+
24
+ emit('regenerate');
25
+ }
26
+ </script>
27
+
28
+ <template>
29
+ <UiTooltip
30
+ :content="ariaLabel"
31
+ side="bottom"
32
+ align="center"
33
+ :delay-duration="0"
34
+ >
35
+ <CkMessageButton
36
+ v-bind="{ ariaLabel }"
37
+ :disabled="disabled"
38
+ @click="handleClick"
39
+ >
40
+ <UiIcon name="repeat" :size="16" aria-hidden="true" />
41
+ </CkMessageButton>
42
+ </UiTooltip>
43
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as CkRegenerateMessageButton } from './CkRegenerateMessageButton.vue';
2
+ export type * from './types';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Regenerate action button for chat messages. Lets the user request a new
3
+ * response for an assistant message. Renders an icon-only button with an
4
+ * accessible label and tooltip.
5
+ *
6
+ * @category Actions
7
+ * @useCases regenerate assistant reply, retry message, request new response, chat message action
8
+ * @keywords regenerate, retry, repeat, action, message, button, icon
9
+ * @related CkMessageButton, CkCopyMessageButton, CkAgentMessage, CkConversation
10
+ */
11
+ export interface CkRegenerateMessageButtonProps {
12
+ /**
13
+ * Whether the button is disabled and ignores clicks.
14
+ * @default false
15
+ */
16
+ disabled?: boolean;
17
+ /**
18
+ * Accessible label and tooltip content for the button.
19
+ * @default 'Regenerate response'
20
+ */
21
+ ariaLabel?: string;
22
+ }
23
+
24
+ export interface CkRegenerateMessageButtonEmits {
25
+ /** Emitted when the button is pressed and not disabled. */
26
+ (e: 'regenerate'): void;
27
+ }
@@ -1,8 +1,19 @@
1
1
  export { CkSendIcon, CkStopIcon } from './icons';
2
2
  export { CkAgentMessage } from './CkAgentMessage';
3
+ export { CkCitation } from './CkCitation';
4
+ export type {
5
+ CkCitationProps,
6
+ CkCitationEmits,
7
+ CkCitationSource,
8
+ } from './CkCitation';
9
+ export { CkCitationCard } from './CkCitationCard';
10
+ export type {
11
+ CkCitationCardProps,
12
+ CkCitationCardEmits,
13
+ } from './CkCitationCard';
3
14
  export { CkConversationLayout } from './CkConversationLayout';
4
15
  export type { CkConversationLayoutProps } from './CkConversationLayout';
5
- export { CkCopyMessageActionButton } from './CkCopyMessageActionButton';
16
+ export { CkCopyMessageButton } from './CkCopyMessageButton';
6
17
  export { CkDropZoneOverlay } from './CkDropZoneOverlay';
7
18
  export type {
8
19
  CkDropZoneOverlayProps,
@@ -36,9 +47,10 @@ export type { CkHistoryWrapperProps } from './CkHistoryWrapper';
36
47
  export { CkMarkdownRenderer } from './CkMarkdownRenderer';
37
48
  export type {
38
49
  CkMarkdownRendererProps,
50
+ CkMarkdownRendererEmits,
39
51
  CkMarkdownElementClasses,
40
52
  } from './CkMarkdownRenderer';
41
- export { CkMessageActionButton } from './CkMessageActionButton';
53
+ export { CkMessageButton } from './CkMessageButton';
42
54
  export { CkModelSelector } from './CkModelSelector';
43
55
  export type {
44
56
  CkModelOption,
@@ -51,5 +63,6 @@ export type { CkPromptMenuButtonProps } from './CkPromptMenuButton';
51
63
  export { CkPromptStopButton } from './CkPromptStopButton';
52
64
  export { CkPromptInput } from './CkPromptInput';
53
65
  export { CkPromptInputDisclaimer } from './CkPromptInputDisclaimer';
66
+ export { CkRegenerateMessageButton } from './CkRegenerateMessageButton';
54
67
  export { CkUserMessage } from './CkUserMessage';
55
68
  export type { CkUserMessageProps } from './CkUserMessage';
@@ -1,4 +1,4 @@
1
- import { CkCopyMessageActionButton } from '../../base/CkCopyMessageActionButton';
1
+ import { CkCopyMessageButton } from '../../base/CkCopyMessageButton';
2
2
  import { CkFeedbackButton } from '../../base/CkFeedbackButton';
3
3
  import type { CkFeedbackValue } from '../../base/CkFeedbackButton';
4
4
  import type {
@@ -292,7 +292,7 @@ const withFooterActionsTemplateSource = `<script setup lang="ts">
292
292
  import { ref } from 'vue';
293
293
  import {
294
294
  CkConversation,
295
- CkCopyMessageActionButton,
295
+ CkCopyMessageButton,
296
296
  CkFeedbackButton,
297
297
  } from '@aleph-alpha/chat-kit';
298
298
  import type { BaseMessage, CkFeedbackValue } from '@aleph-alpha/chat-kit';
@@ -315,7 +315,7 @@ function onFeedback(messageId: string, value: CkFeedbackValue) {
315
315
  <template>
316
316
  <CkConversation :messages="messages" agent-avatar-fallback="AI" style="height: 100%;">
317
317
  <template #agent-message-footer="{ message }">
318
- <CkCopyMessageActionButton :text="getMessageText(message)" />
318
+ <CkCopyMessageButton :text="getMessageText(message)" />
319
319
  <CkFeedbackButton
320
320
  :value="feedback[message.id]?.value ?? null"
321
321
  :locked="feedback[message.id]?.locked ?? false"
@@ -590,7 +590,7 @@ export const WithCustomIcon: Story = {
590
590
 
591
591
  /**
592
592
  * Overrides `#agent-message-footer` to add real action buttons next to each
593
- * assistant reply: `CkCopyMessageActionButton` for clipboard copy and
593
+ * assistant reply: `CkCopyMessageButton` for clipboard copy and
594
594
  * `CkFeedbackButton` for binary thumbs up / thumbs down feedback. The
595
595
  * feedback state is owned by the host and locked once submitted.
596
596
  */
@@ -598,7 +598,7 @@ export const WithFooterActions: Story = {
598
598
  render: () => ({
599
599
  components: {
600
600
  CkConversation,
601
- CkCopyMessageActionButton,
601
+ CkCopyMessageButton,
602
602
  CkFeedbackButton,
603
603
  },
604
604
  setup() {
@@ -618,7 +618,7 @@ export const WithFooterActions: Story = {
618
618
  template: `
619
619
  <CkConversation :messages="messages" agent-avatar-fallback="AI" style="height: 100%;">
620
620
  <template #agent-message-footer="{ message }">
621
- <CkCopyMessageActionButton :text="getMessageText(message)" />
621
+ <CkCopyMessageButton :text="getMessageText(message)" />
622
622
  <CkFeedbackButton
623
623
  :value="feedback[message.id]?.value ?? null"
624
624
  :locked="feedback[message.id]?.locked ?? false"
@@ -3,7 +3,7 @@ import { useChatKitLabels } from '../../../handlers/useChatKitLabels';
3
3
  import type { BaseMessage, MessageTextContent } from '../../../types';
4
4
  import CkAgentMessage from '../../base/CkAgentMessage/CkAgentMessage.vue';
5
5
  import CkConversationLayout from '../../base/CkConversationLayout/CkConversationLayout.vue';
6
- import CkCopyMessageActionButton from '../../base/CkCopyMessageActionButton/CkCopyMessageActionButton.vue';
6
+ import CkCopyMessageButton from '../../base/CkCopyMessageButton/CkCopyMessageButton.vue';
7
7
  import CkMarkdownRenderer from '../../base/CkMarkdownRenderer/CkMarkdownRenderer.vue';
8
8
  import CkUserMessage from '../../base/CkUserMessage/CkUserMessage.vue';
9
9
  import type { CkConversationProps } from './types';
@@ -143,7 +143,7 @@ function getMessageText(message: BaseMessage): string {
143
143
 
144
144
  <template #footer>
145
145
  <slot name="agent-message-footer" :message="message">
146
- <CkCopyMessageActionButton
146
+ <CkCopyMessageButton
147
147
  v-if="getMessageText(message) && !isLoading(message)"
148
148
  :text="getMessageText(message)"
149
149
  :aria-label-copy="labels.copyMessageAction"
@@ -10,7 +10,7 @@ import type { CkMarkdownElementClasses } from '../../base/CkMarkdownRenderer';
10
10
  * @category Messages
11
11
  * @useCases complete chat conversation ui, streaming chat with markdown, assistant chat view, llm conversation component, drop-in chat surface
12
12
  * @keywords conversation, chat, messages, assistant, agent, user, markdown, streaming, avatar
13
- * @related CkConversationLayout, CkAgentMessage, CkUserMessage, CkMarkdownRenderer, CkCopyMessageActionButton, CkInput
13
+ * @related CkConversationLayout, CkAgentMessage, CkUserMessage, CkMarkdownRenderer, CkCopyMessageButton, CkInput
14
14
  */
15
15
  export interface CkConversationProps {
16
16
  /** List of messages to display, in chronological order. */
@@ -1,8 +1,10 @@
1
1
  // Base (presentational) components
2
2
  export {
3
3
  CkAgentMessage,
4
+ CkCitation,
5
+ CkCitationCard,
4
6
  CkConversationLayout,
5
- CkCopyMessageActionButton,
7
+ CkCopyMessageButton,
6
8
  CkDropZoneOverlay,
7
9
  CkFeedbackButton,
8
10
  CkFeedbackDialog,
@@ -10,18 +12,24 @@ export {
10
12
  CkHistoryItem,
11
13
  CkHistoryWrapper,
12
14
  CkMarkdownRenderer,
13
- CkMessageActionButton,
15
+ CkMessageButton,
14
16
  CkModelSelector,
15
17
  CkPromptSendButton,
16
18
  CkPromptMenuButton,
17
19
  CkPromptStopButton,
18
20
  CkPromptInput,
19
21
  CkPromptInputDisclaimer,
22
+ CkRegenerateMessageButton,
20
23
  CkSendIcon,
21
24
  CkStopIcon,
22
25
  CkUserMessage,
23
26
  } from './base';
24
27
  export type {
28
+ CkCitationProps,
29
+ CkCitationEmits,
30
+ CkCitationSource,
31
+ CkCitationCardProps,
32
+ CkCitationCardEmits,
25
33
  CkConversationLayoutProps,
26
34
  CkDropZoneOverlayProps,
27
35
  CkDropZoneOverlayEmits,
@@ -42,6 +50,7 @@ export type {
42
50
  CkHistoryWrapperProps,
43
51
  CkMarkdownElementClasses,
44
52
  CkMarkdownRendererProps,
53
+ CkMarkdownRendererEmits,
45
54
  CkModelOption,
46
55
  CkModelSelectorProps,
47
56
  CkModelSelectorEmits,
@@ -199,33 +199,7 @@ describe('useFileUpload maxFilesPerUpload', () => {
199
199
  });
200
200
  });
201
201
 
202
- it('throws MAX_FILES_EXCEEDED when active files plus new batch exceeds limit', async () => {
203
- const client = createUploadMockClient();
204
- (client.post as ReturnType<typeof vi.fn>).mockResolvedValue([
205
- { id: 'remote-1' },
206
- ]);
207
-
208
- const upload = useFileUpload({
209
- client,
210
- workflowId: 'wf',
211
- storeId: 'ss-1',
212
- maxFilesPerUpload: 3,
213
- });
214
-
215
- upload.files.value.set('existing-1', makeSuccessEntry('existing-1', 'r-1'));
216
- upload.files.value.set('existing-2', makeSuccessEntry('existing-2', 'r-2'));
217
-
218
- await expect(
219
- upload.upload({
220
- id: 'g2',
221
- files: [createFile('a.pdf'), createFile('b.pdf')],
222
- }),
223
- ).rejects.toMatchObject({
224
- code: 'MAX_FILES_EXCEEDED',
225
- });
226
- });
227
-
228
- it('allows upload when active files plus new batch is within limit', async () => {
202
+ it('allows upload when batch is within limit regardless of existing active files', async () => {
229
203
  const client = createUploadMockClient();
230
204
  (client.post as ReturnType<typeof vi.fn>).mockResolvedValue([
231
205
  { id: 'remote-new' },
@@ -239,6 +213,7 @@ describe('useFileUpload maxFilesPerUpload', () => {
239
213
  });
240
214
 
241
215
  upload.files.value.set('existing-1', makeSuccessEntry('existing-1', 'r-1'));
216
+ upload.files.value.set('existing-2', makeSuccessEntry('existing-2', 'r-2'));
242
217
 
243
218
  const result = await upload.upload({
244
219
  id: 'g3',
@@ -247,38 +222,4 @@ describe('useFileUpload maxFilesPerUpload', () => {
247
222
 
248
223
  expect(result.results).toHaveLength(2);
249
224
  });
250
-
251
- it('does not count failed/cancelled/removed files towards active count', async () => {
252
- const client = createUploadMockClient();
253
- (client.post as ReturnType<typeof vi.fn>).mockResolvedValue([
254
- { id: 'remote-new' },
255
- ]);
256
-
257
- const upload = useFileUpload({
258
- client,
259
- workflowId: 'wf',
260
- storeId: 'ss-1',
261
- maxFilesPerUpload: 2,
262
- });
263
-
264
- const failedEntry: FileEntry = {
265
- ...makeEntry('failed-1', 'r-f1'),
266
- status: 'failed',
267
- error: { code: 'UPLOAD_FAILED', message: 'err', occurredAt: 'now' },
268
- };
269
- const cancelledEntry: FileEntry = {
270
- ...makeEntry('cancelled-1', 'r-c1'),
271
- status: 'cancelled',
272
- };
273
-
274
- upload.files.value.set('failed-1', failedEntry);
275
- upload.files.value.set('cancelled-1', cancelledEntry);
276
-
277
- const result = await upload.upload({
278
- id: 'g4',
279
- files: [createFile('a.pdf'), createFile('b.pdf')],
280
- });
281
-
282
- expect(result.results).toHaveLength(2);
283
- });
284
225
  });
@@ -707,17 +707,10 @@ export function useFileUpload(
707
707
  ? params.files
708
708
  : [params.files];
709
709
 
710
- const activeFileCount = [...files.value.values()].filter(
711
- (e) =>
712
- e.status !== 'failed' &&
713
- e.status !== 'cancelled' &&
714
- e.status !== 'removed',
715
- ).length;
716
-
717
- if (activeFileCount + fileList.length > constraints.maxFilesPerUpload) {
710
+ if (fileList.length > constraints.maxFilesPerUpload) {
718
711
  throw new SdkError(
719
712
  'MAX_FILES_EXCEEDED',
720
- `Cannot upload ${fileList.length} file(s) — ${activeFileCount} already active, maximum is ${constraints.maxFilesPerUpload}.`,
713
+ `Cannot upload ${fileList.length} file(s) — maximum per selection is ${constraints.maxFilesPerUpload}.`,
721
714
  );
722
715
  }
723
716