@aleph-alpha/chat-kit 5.11.0 → 5.12.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 (50) hide show
  1. package/dist/{CkHistory.vue_vue_type_script_setup_true_lang-SL1vOAd9.js → CkHistory.vue_vue_type_script_setup_true_lang-CImSzLYs.js} +118 -74
  2. package/dist/chat-kit.css +13 -13
  3. package/dist/components/base/CkCitation/CkCitation.vue.d.ts.map +1 -1
  4. package/dist/components/base/CkCitationLabel/CkCitationLabel.stories.d.ts +39 -0
  5. package/dist/components/base/CkCitationLabel/CkCitationLabel.stories.d.ts.map +1 -0
  6. package/dist/components/base/CkCitationLabel/CkCitationLabel.vue.d.ts +9 -0
  7. package/dist/components/base/CkCitationLabel/CkCitationLabel.vue.d.ts.map +1 -0
  8. package/dist/components/base/CkCitationLabel/index.d.ts +3 -0
  9. package/dist/components/base/CkCitationLabel/index.d.ts.map +1 -0
  10. package/dist/components/base/CkCitationLabel/types.d.ts +44 -0
  11. package/dist/components/base/CkCitationLabel/types.d.ts.map +1 -0
  12. package/dist/components/base/CkFeedbackDialog/CkFeedbackDialog.stories.d.ts +7 -0
  13. package/dist/components/base/CkFeedbackDialog/CkFeedbackDialog.stories.d.ts.map +1 -1
  14. package/dist/components/base/CkFeedbackDialog/CkFeedbackDialog.vue.d.ts +2 -2
  15. package/dist/components/base/CkFeedbackDialog/CkFeedbackDialog.vue.d.ts.map +1 -1
  16. package/dist/components/base/CkFeedbackDialog/types.d.ts +19 -0
  17. package/dist/components/base/CkFeedbackDialog/types.d.ts.map +1 -1
  18. package/dist/components/base/CkFileItemsList/CkFileItemsList.vue.d.ts +1 -1
  19. package/dist/components/base/CkUserMessage/CkUserMessage.vue.d.ts.map +1 -1
  20. package/dist/components/base/index.d.ts +2 -0
  21. package/dist/components/base/index.d.ts.map +1 -1
  22. package/dist/components/composed/CkConversation/CkConversation.stories.d.ts +12 -0
  23. package/dist/components/composed/CkConversation/CkConversation.stories.d.ts.map +1 -1
  24. package/dist/components/index.d.ts +2 -2
  25. package/dist/components/index.d.ts.map +1 -1
  26. package/dist/components/index.js +28 -27
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +29 -28
  30. package/dist/types.d.ts +33 -4
  31. package/dist/types.d.ts.map +1 -1
  32. package/package.json +3 -3
  33. package/src/components/base/CkCitation/CkCitation.spec.ts +11 -0
  34. package/src/components/base/CkCitation/CkCitation.vue +9 -36
  35. package/src/components/base/CkCitationLabel/CkCitationLabel.spec.ts +73 -0
  36. package/src/components/base/CkCitationLabel/CkCitationLabel.stories.ts +86 -0
  37. package/src/components/base/CkCitationLabel/CkCitationLabel.vue +69 -0
  38. package/src/components/base/CkCitationLabel/index.ts +2 -0
  39. package/src/components/base/CkCitationLabel/types.ts +43 -0
  40. package/src/components/base/CkFeedbackDialog/CkFeedbackDialog.spec.ts +36 -0
  41. package/src/components/base/CkFeedbackDialog/CkFeedbackDialog.stories.ts +42 -0
  42. package/src/components/base/CkFeedbackDialog/CkFeedbackDialog.vue +11 -1
  43. package/src/components/base/CkFeedbackDialog/types.ts +20 -0
  44. package/src/components/base/CkUserMessage/CkUserMessage.vue +1 -1
  45. package/src/components/base/index.ts +2 -0
  46. package/src/components/composed/CkConversation/CkConversation.spec.ts +65 -2
  47. package/src/components/composed/CkConversation/CkConversation.stories.ts +136 -0
  48. package/src/components/index.ts +2 -0
  49. package/src/index.ts +2 -0
  50. package/src/types.ts +34 -4
@@ -1,3 +1,5 @@
1
+ import type { CkCitationSource } from '../../base/CkCitation';
2
+ import { CkMarkdownRenderer } from '../../base/CkMarkdownRenderer';
1
3
  import { CkCopyMessageButton } from '../../base/CkCopyMessageButton';
2
4
  import { CkFeedbackButton } from '../../base/CkFeedbackButton';
3
5
  import type { CkFeedbackValue } from '../../base/CkFeedbackButton';
@@ -65,6 +67,53 @@ const markdownContent = [
65
67
  '| Feedback Integration | Planned | High |',
66
68
  ].join('\n');
67
69
 
70
+ const citedAnswer = [
71
+ 'Based on a review of internal documents, the rollout produced two measurable effects:',
72
+ '',
73
+ '- **Adoption:** Departments that received customized training saw a **25% higher adoption rate** of the new tools than those with generic training.[1]',
74
+ '- **Rework:** A lack of initial stakeholder engagement led to significant process rework during the first wave.[2]',
75
+ '',
76
+ 'Both findings are consistent across the quarterly reviews.[1][2]',
77
+ ].join('\n');
78
+
79
+ /** One entry per `[n]` reference in `citedAnswer`, keyed by `index`. */
80
+ const citations: CkCitationSource[] = [
81
+ {
82
+ index: 1,
83
+ fileName: 'Q2_Business_Plan.pdf',
84
+ snippet:
85
+ 'Departments that received customized training saw a 25% higher adoption rate of the new tools compared to those with generic training.',
86
+ locationLabel: 'Page 3',
87
+ url: '/api/v1/search-stores/ss_abc/files/file_123/public-urls',
88
+ },
89
+ {
90
+ index: 2,
91
+ fileName: 'Goal-planning-26.pdf',
92
+ snippet:
93
+ 'Early stakeholder involvement remains the single strongest predictor of a rollout that does not require process rework.',
94
+ locationLabel: 'Page 12',
95
+ },
96
+ ];
97
+
98
+ const citedMessages: BaseMessage[] = [
99
+ {
100
+ id: 'c1',
101
+ role: 'user',
102
+ content: [
103
+ text('What did we learn from the Digital Transformation rollout?'),
104
+ ],
105
+ createdAt: now,
106
+ status: 'completed',
107
+ },
108
+ {
109
+ id: 'c2',
110
+ role: 'assistant',
111
+ content: [text(citedAnswer)],
112
+ createdAt: now,
113
+ status: 'completed',
114
+ },
115
+ ];
116
+
68
117
  const sampleMessages: BaseMessage[] = [
69
118
  {
70
119
  id: '1',
@@ -384,6 +433,51 @@ function getMessageText(message: BaseMessage): string {
384
433
  </CkConversation>
385
434
  </template>`;
386
435
 
436
+ const withCitationsTemplateSource = `<script setup lang="ts">
437
+ import { CkConversation, CkMarkdownRenderer } from '@aleph-alpha/chat-kit';
438
+ import type { BaseMessage, CkCitationSource } from '@aleph-alpha/chat-kit';
439
+
440
+ const messages: BaseMessage[] = [/* ... */];
441
+
442
+ // One entry per \`[n]\` reference in the answer, keyed by \`index\`. Keep the
443
+ // array reference stable so the markdown processor isn't rebuilt on every
444
+ // render.
445
+ const citations: CkCitationSource[] = [
446
+ {
447
+ index: 1,
448
+ fileName: 'Q2_Business_Plan.pdf',
449
+ snippet: 'Departments that received customized training saw a 25% higher adoption rate.',
450
+ locationLabel: 'Page 3',
451
+ url: '/api/v1/search-stores/ss_abc/files/file_123/public-urls',
452
+ },
453
+ ];
454
+
455
+ function getMessageText(message: BaseMessage): string {
456
+ return message.content
457
+ .filter((c) => c.type === 'text')
458
+ .map((c) => c.text)
459
+ .join('');
460
+ }
461
+
462
+ // The card's external-link action is only a request — the host performs the
463
+ // (often auth-proxied) navigation.
464
+ function openSource(url: string): void {
465
+ window.open(url, '_blank', 'noopener');
466
+ }
467
+ </script>
468
+
469
+ <template>
470
+ <CkConversation :messages="messages" agent-avatar-fallback="AI" style="height: 100%;">
471
+ <template #agent-message-content="{ message }">
472
+ <CkMarkdownRenderer
473
+ :content="getMessageText(message)"
474
+ :citations="citations"
475
+ @open-source="openSource"
476
+ />
477
+ </template>
478
+ </CkConversation>
479
+ </template>`;
480
+
387
481
  const streamingSimulationTemplateSource = `<script setup lang="ts">
388
482
  import { CkConversation } from '@aleph-alpha/chat-kit';
389
483
  import type { BaseMessage } from '@aleph-alpha/chat-kit';
@@ -910,6 +1004,48 @@ export const WithCustomAgentContent: Story = {
910
1004
  },
911
1005
  };
912
1006
 
1007
+ /**
1008
+ * Citations are opt-in: override `#agent-message-content` and hand the message's
1009
+ * sources to `CkMarkdownRenderer`. Every `[n]` in the answer whose number
1010
+ * matches a source's `index` becomes a marker that reveals the source on hover
1011
+ * or keyboard activation; unmatched markers stay plain text. `open-source` is
1012
+ * re-emitted for the host to perform the (often auth-proxied) navigation — the
1013
+ * second source here has no `url`, so its card omits the action.
1014
+ *
1015
+ * The footer copy button is unaffected: it copies the message text, so the
1016
+ * `[n]` references travel with a pasted answer.
1017
+ */
1018
+ export const WithCitations: Story = {
1019
+ render: () => ({
1020
+ components: { CkConversation, CkMarkdownRenderer },
1021
+ setup() {
1022
+ function openSource(url: string) {
1023
+ window.open(url, '_blank', 'noopener');
1024
+ }
1025
+ return {
1026
+ messages: citedMessages,
1027
+ citations,
1028
+ getMessageText,
1029
+ openSource,
1030
+ };
1031
+ },
1032
+ template: `
1033
+ <CkConversation :messages="messages" agent-avatar-fallback="AI" style="height: 100%;">
1034
+ <template #agent-message-content="{ message }">
1035
+ <CkMarkdownRenderer
1036
+ :content="getMessageText(message)"
1037
+ :citations="citations"
1038
+ @open-source="openSource"
1039
+ />
1040
+ </template>
1041
+ </CkConversation>
1042
+ `,
1043
+ }),
1044
+ parameters: {
1045
+ docs: { source: { code: withCitationsTemplateSource } },
1046
+ },
1047
+ };
1048
+
913
1049
  /**
914
1050
  * End-to-end streaming scenario: appending a new user message and then
915
1051
  * streaming an assistant reply chunk-by-chunk. Use as a reference for wiring
@@ -4,6 +4,7 @@ export {
4
4
  CkAgentMessageHeader,
5
5
  CkHeaderActivityButton,
6
6
  CkCitation,
7
+ CkCitationLabel,
7
8
  CkCitationCard,
8
9
  CkConversationLayout,
9
10
  CkCopyMessageButton,
@@ -34,6 +35,7 @@ export type {
34
35
  CkCitationProps,
35
36
  CkCitationEmits,
36
37
  CkCitationSource,
38
+ CkCitationLabelProps,
37
39
  CkCitationCardProps,
38
40
  CkCitationCardEmits,
39
41
  CkConversationLayoutProps,
package/src/index.ts CHANGED
@@ -74,6 +74,7 @@ export {
74
74
  CkAgentMessageHeader,
75
75
  CkHeaderActivityButton,
76
76
  CkCitation,
77
+ CkCitationLabel,
77
78
  CkCitationCard,
78
79
  CkConversation,
79
80
  CkConversationLayout,
@@ -106,6 +107,7 @@ export type {
106
107
  CkCitationProps,
107
108
  CkCitationEmits,
108
109
  CkCitationSource,
110
+ CkCitationLabelProps,
109
111
  CkCitationCardProps,
110
112
  CkCitationCardEmits,
111
113
  CkConversationLayoutProps,
package/src/types.ts CHANGED
@@ -68,6 +68,36 @@ export type MessageContent =
68
68
  | MessageToolContent
69
69
  | MessageReasoningContent;
70
70
 
71
+ declare global {
72
+ /**
73
+ * Extension point for {@link MessageMetadata}. Consumers declare their
74
+ * well-known metadata keys here and get them typed on every message,
75
+ * without chat-kit knowing what any of them mean:
76
+ *
77
+ * ```ts
78
+ * // app/src/types/chat-kit.d.ts
79
+ * declare global {
80
+ * interface ChatKitMessageMetadata {
81
+ * responseId?: string;
82
+ * citations?: CitationManifest;
83
+ * }
84
+ * }
85
+ * export {};
86
+ * ```
87
+ *
88
+ * Declare every key **optional**: chat-kit itself never populates them, and
89
+ * a message can reach a consumer before its host has stamped anything (mid
90
+ * stream, or on an optimistic node).
91
+ *
92
+ * This is a `declare global` interface rather than a module augmentation
93
+ * because `MessageMetadata` is re-exported through the package barrel —
94
+ * `declare module '@aleph-alpha/chat-kit'` does not merge across a
95
+ * re-export, and would silently type nothing.
96
+ */
97
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
98
+ interface ChatKitMessageMetadata {}
99
+ }
100
+
71
101
  /**
72
102
  * Open-ended metadata bag carried alongside a message. chat-kit is
73
103
  * intentionally agnostic about its contents — adapter authors
@@ -75,11 +105,11 @@ export type MessageContent =
75
105
  * through the tree → linear path projection, but never inspect it.
76
106
  *
77
107
  * Consumers attach their own well-known keys (attachments, citations,
78
- * ratings, …) and define their own typed projections at the read site
79
- * rather than extending this base type. That keeps the handler API stable
80
- * even as the shape of what gets stored on a message evolves.
108
+ * ratings, …). Declaring them on {@link ChatKitMessageMetadata} types those
109
+ * reads everywhere; the retained index signature keeps any other key legal,
110
+ * so the handler API stays stable as the stored shape evolves.
81
111
  */
82
- export type MessageMetadata = Record<string, unknown>;
112
+ export type MessageMetadata = ChatKitMessageMetadata & Record<string, unknown>;
83
113
 
84
114
  export interface BaseMessage {
85
115
  id: string;