@aleph-alpha/chat-kit 1.0.0 → 1.1.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 (118) hide show
  1. package/dist/{CkInput.vue_vue_type_script_setup_true_lang-744ZHsQU.js → CkInput.vue_vue_type_script_setup_true_lang-DpYyyCgU.js} +23 -68
  2. package/dist/components/base/CkHistoryItem/CkHistoryItem.vue.d.ts +3 -4
  3. package/dist/components/base/CkHistoryItem/CkHistoryItem.vue.d.ts.map +1 -1
  4. package/dist/components/base/CkHistoryItem/types.d.ts +3 -2
  5. package/dist/components/base/CkHistoryItem/types.d.ts.map +1 -1
  6. package/dist/components/base/CkPromptStopButton/CkPromptStopButton.vue.d.ts.map +1 -1
  7. package/dist/components/index.js +1 -1
  8. package/dist/index.js +1 -1
  9. package/package.json +5 -5
  10. package/src/components/base/CkAgentMessage/CkAgentMessage.spec.ts +91 -0
  11. package/src/components/base/CkAgentMessage/CkAgentMessage.stories.ts +215 -0
  12. package/src/components/base/CkAgentMessage/CkAgentMessage.vue +25 -0
  13. package/src/components/base/CkAgentMessage/index.ts +2 -0
  14. package/src/components/base/CkAgentMessage/types.ts +11 -0
  15. package/src/components/base/CkConversationLayout/CkConversationLayout.spec.ts +129 -0
  16. package/src/components/base/CkConversationLayout/CkConversationLayout.stories.ts +251 -0
  17. package/src/components/base/CkConversationLayout/CkConversationLayout.vue +206 -0
  18. package/src/components/base/CkConversationLayout/index.ts +2 -0
  19. package/src/components/base/CkConversationLayout/types.ts +18 -0
  20. package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.spec.ts +89 -0
  21. package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.stories.ts +70 -0
  22. package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.vue +110 -0
  23. package/src/components/base/CkCopyMessageActionButton/index.ts +2 -0
  24. package/src/components/base/CkCopyMessageActionButton/types.ts +43 -0
  25. package/src/components/base/CkHistoryItem/CkHistoryItem.spec.ts +42 -0
  26. package/src/components/base/CkHistoryItem/CkHistoryItem.stories.ts +230 -0
  27. package/src/components/base/CkHistoryItem/CkHistoryItem.vue +285 -0
  28. package/src/components/base/CkHistoryItem/activeIndicator.ts +15 -0
  29. package/src/components/base/CkHistoryItem/index.ts +2 -0
  30. package/src/components/base/CkHistoryItem/types.ts +111 -0
  31. package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.spec.ts +26 -0
  32. package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.stories.ts +149 -0
  33. package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.vue +36 -0
  34. package/src/components/base/CkHistoryWrapper/index.ts +2 -0
  35. package/src/components/base/CkHistoryWrapper/types.ts +16 -0
  36. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.spec.ts +348 -0
  37. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.stories.ts +382 -0
  38. package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.vue +89 -0
  39. package/src/components/base/CkMarkdownRenderer/defaultMarkdownClasses.ts +19 -0
  40. package/src/components/base/CkMarkdownRenderer/index.ts +5 -0
  41. package/src/components/base/CkMarkdownRenderer/types.ts +53 -0
  42. package/src/components/base/CkMessageActionButton/CkMessageActionButton.spec.ts +40 -0
  43. package/src/components/base/CkMessageActionButton/CkMessageActionButton.stories.ts +56 -0
  44. package/src/components/base/CkMessageActionButton/CkMessageActionButton.vue +23 -0
  45. package/src/components/base/CkMessageActionButton/index.ts +2 -0
  46. package/src/components/base/CkMessageActionButton/types.ts +21 -0
  47. package/src/components/base/CkPromptActionButton/CkPromptActionButton.spec.ts +52 -0
  48. package/src/components/base/CkPromptActionButton/CkPromptActionButton.stories.ts +126 -0
  49. package/src/components/base/CkPromptActionButton/CkPromptActionButton.vue +25 -0
  50. package/src/components/base/CkPromptActionButton/index.ts +2 -0
  51. package/src/components/base/CkPromptActionButton/types.ts +32 -0
  52. package/src/components/base/CkPromptInput/CkPromptInput.spec.ts +181 -0
  53. package/src/components/base/CkPromptInput/CkPromptInput.stories.ts +224 -0
  54. package/src/components/base/CkPromptInput/CkPromptInput.vue +104 -0
  55. package/src/components/base/CkPromptInput/index.ts +2 -0
  56. package/src/components/base/CkPromptInput/types.ts +39 -0
  57. package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.spec.ts +40 -0
  58. package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.stories.ts +103 -0
  59. package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.vue +16 -0
  60. package/src/components/base/CkPromptInputDisclaimer/index.ts +2 -0
  61. package/src/components/base/CkPromptInputDisclaimer/types.ts +17 -0
  62. package/src/components/base/CkPromptStopButton/CkPromptStopButton.spec.ts +64 -0
  63. package/src/components/base/CkPromptStopButton/CkPromptStopButton.stories.ts +81 -0
  64. package/src/components/base/CkPromptStopButton/CkPromptStopButton.vue +27 -0
  65. package/src/components/base/CkPromptStopButton/index.ts +2 -0
  66. package/src/components/base/CkPromptStopButton/types.ts +28 -0
  67. package/src/components/base/CkUserMessage/CkUserMessage.spec.ts +20 -0
  68. package/src/components/base/CkUserMessage/CkUserMessage.stories.ts +112 -0
  69. package/src/components/base/CkUserMessage/CkUserMessage.vue +19 -0
  70. package/src/components/base/CkUserMessage/index.ts +2 -0
  71. package/src/components/base/CkUserMessage/types.ts +14 -0
  72. package/src/components/base/icons/CkSendIcon.vue +22 -0
  73. package/src/components/base/icons/CkStopIcon.vue +18 -0
  74. package/src/components/base/icons/index.ts +2 -0
  75. package/src/components/base/index.ts +21 -0
  76. package/src/components/composed/CkConversation/CkConversation.spec.ts +439 -0
  77. package/src/components/composed/CkConversation/CkConversation.stories.ts +642 -0
  78. package/src/components/composed/CkConversation/CkConversation.vue +146 -0
  79. package/src/components/composed/CkConversation/index.ts +2 -0
  80. package/src/components/composed/CkConversation/types.ts +37 -0
  81. package/src/components/composed/CkHistory/CkHistory.spec.ts +327 -0
  82. package/src/components/composed/CkHistory/CkHistory.stories.ts +373 -0
  83. package/src/components/composed/CkHistory/CkHistory.vue +126 -0
  84. package/src/components/composed/CkHistory/index.ts +2 -0
  85. package/src/components/composed/CkHistory/types.ts +72 -0
  86. package/src/components/composed/CkInput/CkInput.spec.ts +191 -0
  87. package/src/components/composed/CkInput/CkInput.stories.ts +438 -0
  88. package/src/components/composed/CkInput/CkInput.vue +104 -0
  89. package/src/components/composed/CkInput/index.ts +2 -0
  90. package/src/components/composed/CkInput/types.ts +60 -0
  91. package/src/components/composed/index.ts +5 -0
  92. package/src/components/index.ts +34 -0
  93. package/src/composables/index.ts +9 -0
  94. package/src/composables/types.ts +36 -0
  95. package/src/composables/useChat.ts +18 -0
  96. package/src/composables/useConversations.spec.ts +557 -0
  97. package/src/composables/useConversations.ts +321 -0
  98. package/src/handlers/index.ts +9 -0
  99. package/src/handlers/useChatKitLabels.spec.ts +290 -0
  100. package/src/handlers/useChatKitLabels.ts +96 -0
  101. package/src/handlers/useMarkdownParser.spec.ts +112 -0
  102. package/src/handlers/useMarkdownParser.ts +47 -0
  103. package/src/handlers/useMessageHandler.spec.ts +535 -0
  104. package/src/handlers/useMessageHandler.ts +138 -0
  105. package/src/helpers/conversationTree.spec.ts +423 -0
  106. package/src/helpers/conversationTree.ts +117 -0
  107. package/src/helpers/generateId.ts +5 -0
  108. package/src/helpers/index.ts +4 -0
  109. package/src/helpers/secondsToDate.ts +7 -0
  110. package/src/helpers/toError.ts +8 -0
  111. package/src/index.ts +79 -0
  112. package/src/services/ChatService.ts +60 -0
  113. package/src/services/MockChatService.ts +47 -0
  114. package/src/services/index.ts +12 -0
  115. package/src/services/types.ts +92 -0
  116. package/src/test-setup.ts +12 -0
  117. package/src/test-utils/createTextPlugin.ts +9 -0
  118. package/src/types.ts +47 -0
@@ -1,6 +1,6 @@
1
- import { defineComponent, openBlock, createElementBlock, createElementVNode, renderSlot, createCommentVNode, ref, onMounted, nextTick, onUnmounted, watch, Fragment, renderList, normalizeStyle, createBlock, unref, mergeProps, withCtx, createVNode, Transition, toDisplayString, Comment, cloneVNode, h, useAttrs, useSlots, computed, normalizeClass, withModifiers, resolveDynamicComponent, toRefs, useId, useTemplateRef, createTextVNode, createSlots, normalizeProps, guardReactiveProps } from "vue";
1
+ import { defineComponent, openBlock, createElementBlock, createElementVNode, renderSlot, createCommentVNode, ref, onMounted, nextTick, onUnmounted, watch, Fragment, renderList, normalizeStyle, createBlock, unref, mergeProps, withCtx, createVNode, Transition, toDisplayString, useAttrs, useSlots, computed, normalizeClass, withModifiers, resolveDynamicComponent, toRefs, h, useId, useTemplateRef, createTextVNode, createSlots, normalizeProps, guardReactiveProps } from "vue";
2
2
  import { a as useMarkdownParser, u as useChatKitLabels } from "./useChatKitLabels-Dvi2FmjE.js";
3
- import { UiButton, UiTooltip, UiIcon, UiPopover, UiPopoverTrigger, UiPopoverContent, UiIconButton, UiAvatar, UiAvatarImage, UiSpinner, UiAvatarFallback, UiSidebarPopoverMenu, UiSidebarPopoverMenuItem } from "@aleph-alpha/ui-library";
3
+ import { UiButton, UiTooltip, UiIcon, Primitive, UiPopover, UiPopoverTrigger, UiPopoverContent, UiAvatar, UiAvatarImage, UiSpinner, UiAvatarFallback, UiSidebarPopoverMenu, UiSidebarPopoverMenuItem } from "@aleph-alpha/ui-library";
4
4
  const _hoisted_1$8 = {
5
5
  xmlns: "http://www.w3.org/2000/svg",
6
6
  width: "16",
@@ -375,60 +375,6 @@ const _export_sfc = (sfc, props) => {
375
375
  return target;
376
376
  };
377
377
  const CkCopyMessageActionButton = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-f77a1193"]]);
378
- function renderSlotFragments(children) {
379
- if (!children) return [];
380
- return children.flatMap((child) => {
381
- if (child.type === Fragment) return renderSlotFragments(child.children);
382
- return [child];
383
- });
384
- }
385
- const Slot = defineComponent({
386
- name: "PrimitiveSlot",
387
- inheritAttrs: false,
388
- setup(_, { attrs, slots }) {
389
- return () => {
390
- if (!slots.default) return null;
391
- const children = renderSlotFragments(slots.default());
392
- const firstNonCommentChildrenIndex = children.findIndex((child) => child.type !== Comment);
393
- if (firstNonCommentChildrenIndex === -1) return children;
394
- const firstNonCommentChildren = children[firstNonCommentChildrenIndex];
395
- delete firstNonCommentChildren.props?.ref;
396
- const mergedProps = firstNonCommentChildren.props ? mergeProps(attrs, firstNonCommentChildren.props) : attrs;
397
- const cloned = cloneVNode({
398
- ...firstNonCommentChildren,
399
- props: {}
400
- }, mergedProps);
401
- if (children.length === 1) return cloned;
402
- children[firstNonCommentChildrenIndex] = cloned;
403
- return children;
404
- };
405
- }
406
- });
407
- const SELF_CLOSING_TAGS = [
408
- "area",
409
- "img",
410
- "input"
411
- ];
412
- const Primitive = defineComponent({
413
- name: "Primitive",
414
- inheritAttrs: false,
415
- props: {
416
- asChild: {
417
- type: Boolean,
418
- default: false
419
- },
420
- as: {
421
- type: [String, Object],
422
- default: "div"
423
- }
424
- },
425
- setup(props, { attrs, slots }) {
426
- const asTag = props.asChild ? "template" : props.as;
427
- if (typeof asTag === "string" && SELF_CLOSING_TAGS.includes(asTag)) return () => h(asTag, attrs);
428
- if (asTag !== "template") return () => h(props.as, attrs, { default: slots.default });
429
- return () => h(Slot, attrs, { default: slots.default });
430
- }
431
- });
432
378
  const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = 'before:absolute before:z-10 before:top-1/2 before:left-0 before:h-1/2 before:w-0.5 before:-translate-y-1/2 before:origin-left before:scale-x-0 before:rounded-full before:bg-background-accent-default before:opacity-0 before:transition-[transform,opacity] before:duration-200 before:ease-linear before:content-[""] data-[active=true]:before:scale-x-100 data-[active=true]:before:opacity-100';
433
379
  const _hoisted_1$3 = ["data-active"];
434
380
  const _hoisted_2$2 = { class: "min-w-0 flex-1" };
@@ -472,9 +418,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
472
418
  actionPopoverSide: { default: "right" },
473
419
  actionPopoverAlign: { default: "start" },
474
420
  actionPopoverSideOffset: { default: 8 },
475
- actionPopoverContentClass: {},
476
- asChild: { type: Boolean },
477
- as: { default: "button" }
421
+ actionPopoverContentClass: {}
478
422
  },
479
423
  emits: ["action-click"],
480
424
  setup(__props, { emit: __emit }) {
@@ -512,10 +456,10 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
512
456
  // Whole-row focus ring: first tab lands on the main row control; second tab on the action button — both are inside this container.
513
457
  // `:has(:focus-visible)` instead of `:focus-within` so mouse clicks on the row don't flash a keyboard focus ring.
514
458
  "has-[:focus-visible]:border-border-surface-focus-ring has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50",
515
- // Row hover/active tint — flat `default` hover-mix color. Hover is suppressed while the
516
- // pointer/focus is on the action column so the icon's own tint does not stack on top.
517
- props.isActive ? "bg-background-surface-primary-hover-default" : "",
518
- !pointerOnAction.value ? "hover:bg-background-surface-primary-hover-default" : "",
459
+ // Row hover/active fill. Hover is suppressed while the
460
+ // pointer/focus is on the action column so the icon's own fill does not stack on top.
461
+ (props.isActive || !pointerOnAction.value) && "hover:bg-background-surface-muted-subtle",
462
+ props.isActive && "bg-background-surface-muted-subtle",
519
463
  CHAT_HISTORY_ACTIVE_INDICATOR_CLASS
520
464
  ]);
521
465
  const itemClass = computed(() => [
@@ -541,16 +485,26 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
541
485
  "relative z-10 inline-flex size-8 shrink-0 items-center justify-center rounded-sm border border-transparent text-content-on-surface-primary outline-hidden transition-colors",
542
486
  "[&_svg]:size-4 [&_svg]:shrink-0",
543
487
  "focus-visible:ring-0 focus-visible:outline-none",
544
- pointerOnAction.value ? "bg-background-surface-primary-hover-default border-border-button-outlined" : ""
488
+ pointerOnAction.value && "bg-background-surface-muted-subtle border-border-button-outlined"
545
489
  ]);
546
490
  const actionPopoverPanelClass = computed(() => [
547
491
  "w-auto min-w-48 max-w-sm p-0 bg-background-surface-secondary",
548
492
  props.actionPopoverContentClass
549
493
  ]);
550
494
  const passthroughAttrs = computed(() => {
551
- const { class: _class, ...rest } = attrs;
495
+ const {
496
+ class: _class,
497
+ as: _as,
498
+ asChild: _asChild,
499
+ "as-child": _asChildAttr,
500
+ ...rest
501
+ } = attrs;
552
502
  return rest;
553
503
  });
504
+ const primitiveAs = computed(() => attrs.as ?? "button");
505
+ const primitiveAsChild = computed(
506
+ () => attrs.asChild === true || attrs.asChild === "" || attrs["as-child"] === true || attrs["as-child"] === ""
507
+ );
554
508
  function onActionClick(event) {
555
509
  event.stopPropagation();
556
510
  const el = event.currentTarget;
@@ -567,8 +521,8 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
567
521
  class: normalizeClass(containerClass.value)
568
522
  }, [
569
523
  createVNode(unref(Primitive), mergeProps(passthroughAttrs.value, {
570
- as: props.as,
571
- "as-child": props.asChild,
524
+ as: primitiveAs.value,
525
+ "as-child": primitiveAsChild.value,
572
526
  "data-active": props.isActive,
573
527
  class: itemClass.value
574
528
  }), {
@@ -823,7 +777,8 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
823
777
  setup(__props) {
824
778
  const props = __props;
825
779
  return (_ctx, _cache) => {
826
- return openBlock(), createBlock(unref(UiIconButton), mergeProps({ ariaLabel: __props.ariaLabel }, {
780
+ return openBlock(), createBlock(unref(UiButton), mergeProps({ ariaLabel: __props.ariaLabel }, {
781
+ size: "icon-sm",
827
782
  disabled: props.disabled,
828
783
  class: "!bg-brand-bg-brand hover:!bg-brand-bg-brand-hover !text-brand-content-default !rounded-md",
829
784
  onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
@@ -1,13 +1,13 @@
1
- import type { CkHistoryItemProps } from './types';
1
+ import type { CkHistoryItemOwnProps } from './types';
2
2
  declare var __VLS_7: {}, __VLS_37: {};
3
3
  type __VLS_Slots = {} & {
4
4
  meta?: (props: typeof __VLS_7) => any;
5
5
  } & {
6
6
  'action-popover'?: (props: typeof __VLS_37) => any;
7
7
  };
8
- declare const __VLS_base: import("vue").DefineComponent<CkHistoryItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ declare const __VLS_base: import("vue").DefineComponent<CkHistoryItemOwnProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
9
  "action-click": (event: MouseEvent) => any;
10
- }, string, import("vue").PublicProps, Readonly<CkHistoryItemProps> & Readonly<{
10
+ }, string, import("vue").PublicProps, Readonly<CkHistoryItemOwnProps> & Readonly<{
11
11
  "onAction-click"?: ((event: MouseEvent) => any) | undefined;
12
12
  }>, {
13
13
  isActive: boolean;
@@ -19,7 +19,6 @@ declare const __VLS_base: import("vue").DefineComponent<CkHistoryItemProps, {},
19
19
  actionPopoverSide: "top" | "right" | "bottom" | "left";
20
20
  actionPopoverAlign: "start" | "center" | "end";
21
21
  actionPopoverSideOffset: number;
22
- as: import("reka-ui").AsTag | import("vue").Component;
23
22
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
23
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
24
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"CkHistoryItem.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/CkHistoryItem.vue"],"names":[],"mappings":"AA8RA,OAAO,KAAK,EAAsB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA6ctE,QAAA,IAAI,OAAO,IAAU,EAAE,QAAQ,IAAY,CAAE;AAC7C,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GACzC;IAAE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAKzD,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;6EAId,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"CkHistoryItem.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/CkHistoryItem.vue"],"names":[],"mappings":"AA0SA,OAAO,KAAK,EAAsB,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA0dzE,QAAA,IAAI,OAAO,IAAU,EAAE,QAAQ,IAAY,CAAE;AAC7C,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GACzC;IAAE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAKzD,QAAA,MAAM,UAAU;;;;;;;;;;;;;;6EAId,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { Component, HTMLAttributes } from 'vue';
2
- import type { PrimitiveProps } from 'reka-ui';
2
+ import type { PrimitiveProps } from '@aleph-alpha/ui-library';
3
3
  /**
4
4
  * A single chat history entry with title, optional meta line, active
5
5
  * indicator, and a trailing action control (plain button or popover).
@@ -10,7 +10,8 @@ import type { PrimitiveProps } from 'reka-ui';
10
10
  * @keywords chat, history, item, row, conversation, thread
11
11
  * @related CkHistoryWrapper
12
12
  */
13
- export interface CkHistoryItemProps extends PrimitiveProps {
13
+ export type CkHistoryItemProps = PrimitiveProps & CkHistoryItemOwnProps;
14
+ export interface CkHistoryItemOwnProps {
14
15
  /**
15
16
  * Main title of the history item.
16
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAExD;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAEhD;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,yBAAyB,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG,qBAAqB,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAExD;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAEhD;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,yBAAyB,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;CACrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"CkPromptStopButton.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkPromptStopButton/CkPromptStopButton.vue"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AA2EvD,QAAA,IAAI,QAAQ,IAAW,CAAE;AACzB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAKhD,QAAA,MAAM,UAAU;;;;;;;6EAId,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"CkPromptStopButton.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkPromptStopButton/CkPromptStopButton.vue"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AA6EvD,QAAA,IAAI,QAAQ,IAAW,CAAE;AACzB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAKhD,QAAA,MAAM,UAAU;;;;;;;6EAId,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1,4 +1,4 @@
1
- import { _, a, b, C, c, d, e, f, g, h, i, j, k, l, m, n, o } from "../CkInput.vue_vue_type_script_setup_true_lang-744ZHsQU.js";
1
+ import { _, a, b, C, c, d, e, f, g, h, i, j, k, l, m, n, o } from "../CkInput.vue_vue_type_script_setup_true_lang-DpYyyCgU.js";
2
2
  export {
3
3
  _ as CkAgentMessage,
4
4
  a as CkConversation,
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { C } from "./ChatService-LogwJNxh.js";
2
2
  import { u } from "./useMessageHandler-uLHNac39.js";
3
3
  import { C as C2, d, p, u as u2, a } from "./useChatKitLabels-Dvi2FmjE.js";
4
4
  import { u as u3, a as a2 } from "./useConversations-Ca242D2P.js";
5
- import { _, a as a3, b, C as C3, c, d as d2, e, f, g, h, i, j, k, l, m, n, o } from "./CkInput.vue_vue_type_script_setup_true_lang-744ZHsQU.js";
5
+ import { _, a as a3, b, C as C3, c, d as d2, e, f, g, h, i, j, k, l, m, n, o } from "./CkInput.vue_vue_type_script_setup_true_lang-DpYyyCgU.js";
6
6
  export {
7
7
  C2 as CHAT_KIT_LABELS,
8
8
  C as ChatService,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aleph-alpha/chat-kit",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Chat kit package for building chat interfaces with Vue",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,7 +29,8 @@
29
29
  }
30
30
  },
31
31
  "files": [
32
- "dist"
32
+ "dist",
33
+ "src"
33
34
  ],
34
35
  "keywords": [
35
36
  "chat",
@@ -58,13 +59,12 @@
58
59
  },
59
60
  "dependencies": {
60
61
  "dompurify": "^3.3.2",
61
- "reka-ui": "^2.7.0",
62
62
  "rehype-stringify": "^10.0.1",
63
63
  "remark-gfm": "^4.0.1",
64
64
  "remark-parse": "^11.0.0",
65
65
  "remark-rehype": "^11.1.2",
66
66
  "unified": "^11.0.5",
67
- "@aleph-alpha/ui-library": "2.0.0"
67
+ "@aleph-alpha/ui-library": "2.2.0"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@storybook/addon-a11y": "10.2.17",
@@ -89,7 +89,7 @@
89
89
  "vitest": "4.0.15",
90
90
  "vue": "^3.5.27",
91
91
  "vue-tsc": "^3.2.4",
92
- "@aleph-alpha/config-css": "1.0.0"
92
+ "@aleph-alpha/config-css": "1.1.0"
93
93
  },
94
94
  "scripts": {
95
95
  "build": "vite build && vue-tsc --project tsconfig.build.json --declaration --emitDeclarationOnly --outDir dist",
@@ -0,0 +1,91 @@
1
+ import CkAgentMessage from './CkAgentMessage.vue';
2
+ import { render, screen } from '@testing-library/vue';
3
+
4
+ describe('CkAgentMessage', () => {
5
+ describe('header', () => {
6
+ it('displays custom header slot content', () => {
7
+ render(CkAgentMessage, {
8
+ slots: { header: 'Custom Header' },
9
+ });
10
+
11
+ expect(screen.getByText('Custom Header')).toBeInTheDocument();
12
+ });
13
+
14
+ it('hides the header section when no header slot is provided', () => {
15
+ const { container } = render(CkAgentMessage, {
16
+ slots: { default: 'Some content' },
17
+ });
18
+
19
+ expect(
20
+ container.querySelector('.text-sm.font-bold'),
21
+ ).not.toBeInTheDocument();
22
+ });
23
+ });
24
+
25
+ describe('content', () => {
26
+ it('displays message content from the default slot', () => {
27
+ render(CkAgentMessage, {
28
+ slots: { default: '<p>Agent response content</p>' },
29
+ });
30
+
31
+ expect(screen.getByText('Agent response content')).toBeInTheDocument();
32
+ });
33
+ });
34
+
35
+ describe('icon', () => {
36
+ it('displays the icon when provided via slot', () => {
37
+ render(CkAgentMessage, {
38
+ slots: { icon: '<img src="" alt="bot-icon" />' },
39
+ });
40
+
41
+ expect(screen.getByAltText('bot-icon')).toBeInTheDocument();
42
+ });
43
+
44
+ it('renders the icon container only when the icon slot is provided', () => {
45
+ const { container } = render(CkAgentMessage, {
46
+ slots: { icon: '<img src="" alt="bot-icon" />' },
47
+ });
48
+
49
+ expect(
50
+ container.querySelector(
51
+ '.flex.flex-shrink-0.items-center.justify-center',
52
+ ),
53
+ ).toBeInTheDocument();
54
+ });
55
+
56
+ it('does not render the icon container when no icon slot is provided', () => {
57
+ const { container } = render(CkAgentMessage, {
58
+ slots: { default: 'Some content' },
59
+ });
60
+
61
+ expect(
62
+ container.querySelector(
63
+ '.flex.flex-shrink-0.items-center.justify-center',
64
+ ),
65
+ ).not.toBeInTheDocument();
66
+ });
67
+ });
68
+
69
+ describe('footer', () => {
70
+ it('displays footer actions when the footer slot is provided', () => {
71
+ render(CkAgentMessage, {
72
+ slots: { footer: '<button>Copy</button><button>Retry</button>' },
73
+ });
74
+
75
+ expect(screen.getByText('Copy')).toBeInTheDocument();
76
+ expect(screen.getByText('Retry')).toBeInTheDocument();
77
+ });
78
+
79
+ it('does not display a footer area when no footer slot is provided', () => {
80
+ const { container } = render(CkAgentMessage, {
81
+ slots: { default: 'Some content' },
82
+ });
83
+
84
+ expect(screen.getByText('Some content')).toBeInTheDocument();
85
+ // Footer buttons should not exist
86
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
87
+ // The container should not have empty footer wrappers
88
+ expect(container.textContent).not.toBe('');
89
+ });
90
+ });
91
+ });
@@ -0,0 +1,215 @@
1
+ import CkAgentMessage from './CkAgentMessage.vue';
2
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
3
+
4
+ const meta: Meta<typeof CkAgentMessage> = {
5
+ title: 'Base/CkAgentMessage',
6
+ component: CkAgentMessage,
7
+ tags: ['autodocs'],
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ const defaultTemplateSource = `<script setup lang="ts">
14
+ import { CkAgentMessage } from '@aleph-alpha/chat-kit';
15
+ </script>
16
+
17
+ <template>
18
+ <CkAgentMessage>
19
+ <template #icon>
20
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
21
+ AI
22
+ </div>
23
+ </template>
24
+ <p>Based on a review of internal documents, here are the key lessons learned.</p>
25
+ </CkAgentMessage>
26
+ </template>`;
27
+
28
+ const withFooterActionsTemplateSource = `<script setup lang="ts">
29
+ import { CkAgentMessage } from '@aleph-alpha/chat-kit';
30
+ </script>
31
+
32
+ <template>
33
+ <CkAgentMessage>
34
+ <template #icon>
35
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
36
+ AI
37
+ </div>
38
+ </template>
39
+ <p>Research completed. Ask any follow-up questions as needed.</p>
40
+ <template #footer>
41
+ <button class="p-1 opacity-60 hover:opacity-100">Copy</button>
42
+ <button class="p-1 opacity-60 hover:opacity-100">Regenerate</button>
43
+ </template>
44
+ </CkAgentMessage>
45
+ </template>`;
46
+
47
+ const withRichContentTemplateSource = `<script setup lang="ts">
48
+ import { CkAgentMessage } from '@aleph-alpha/chat-kit';
49
+ </script>
50
+
51
+ <template>
52
+ <CkAgentMessage>
53
+ <template #icon>
54
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
55
+ AI
56
+ </div>
57
+ </template>
58
+ <div>
59
+ <p>Key lessons learned from the project:</p>
60
+ <ul class="mt-1 list-disc pl-4">
61
+ <li><strong>Stakeholder Involvement:</strong> Early and continuous stakeholder involvement.</li>
62
+ <li><strong>User Training:</strong> Hands-on training beats generic sessions.</li>
63
+ </ul>
64
+ </div>
65
+ <template #footer>
66
+ <button class="p-1 opacity-60 hover:opacity-100">Copy</button>
67
+ </template>
68
+ </CkAgentMessage>
69
+ </template>`;
70
+
71
+ const withCustomHeaderTemplateSource = `<script setup lang="ts">
72
+ import { CkAgentMessage } from '@aleph-alpha/chat-kit';
73
+ </script>
74
+
75
+ <template>
76
+ <CkAgentMessage>
77
+ <template #icon>
78
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
79
+ AI
80
+ </div>
81
+ </template>
82
+ <template #header>
83
+ <span>Custom Agent</span>
84
+ <span class="text-core-content-quaternary ml-2 text-xs font-normal">v2.1</span>
85
+ </template>
86
+ <p>Hello! How can I assist you today?</p>
87
+ </CkAgentMessage>
88
+ </template>`;
89
+
90
+ const withoutIconTemplateSource = `<script setup lang="ts">
91
+ import { CkAgentMessage } from '@aleph-alpha/chat-kit';
92
+ </script>
93
+
94
+ <template>
95
+ <CkAgentMessage>
96
+ <p>A message from an agent without a custom icon.</p>
97
+ </CkAgentMessage>
98
+ </template>`;
99
+
100
+ /**
101
+ * Standard agent reply with an icon slot and a body slot. Use as the default
102
+ * layout for assistant messages in a conversation.
103
+ */
104
+ export const Default: Story = {
105
+ render: () => ({
106
+ components: { CkAgentMessage },
107
+ template: `
108
+ <CkAgentMessage>
109
+ <template #icon>
110
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
111
+ AI
112
+ </div>
113
+ </template>
114
+ <p>Based on a review of internal documents, here are the key lessons learned and best practices from the 'Digital Transformation Phase 1' project, broken down by category.</p>
115
+ </CkAgentMessage>
116
+ `,
117
+ }),
118
+ parameters: { docs: { source: { code: defaultTemplateSource } } },
119
+ };
120
+
121
+ /**
122
+ * Adds action buttons (copy, regenerate, etc.) via the `footer` slot.
123
+ * Use when messages need post-response interactions.
124
+ */
125
+ export const WithFooterActions: Story = {
126
+ render: () => ({
127
+ components: { CkAgentMessage },
128
+ template: `
129
+ <CkAgentMessage>
130
+ <template #icon>
131
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
132
+ AI
133
+ </div>
134
+ </template>
135
+ <p>Research completed. Ask any follow-up questions as needed.</p>
136
+ <template #footer>
137
+ <button class="p-1 opacity-60 hover:opacity-100">Copy</button>
138
+ <button class="p-1 opacity-60 hover:opacity-100">Regenerate</button>
139
+ </template>
140
+ </CkAgentMessage>
141
+ `,
142
+ }),
143
+ parameters: { docs: { source: { code: withFooterActionsTemplateSource } } },
144
+ };
145
+
146
+ /**
147
+ * Arbitrary rich content in the default slot — lists, bold text, etc.
148
+ * Use when you are rendering structured answers directly (rather than via CkMarkdownRenderer).
149
+ */
150
+ export const WithRichContent: Story = {
151
+ render: () => ({
152
+ components: { CkAgentMessage },
153
+ template: `
154
+ <CkAgentMessage>
155
+ <template #icon>
156
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
157
+ AI
158
+ </div>
159
+ </template>
160
+ <div>
161
+ <p>Based on a review of internal documents, here are the key lessons learned:</p>
162
+ <ul class="mt-1 list-disc pl-4">
163
+ <li><strong>Stakeholder Involvement:</strong> Early and continuous stakeholder involvement.</li>
164
+ <li><strong>User Training:</strong> Hands-on training was far more effective than generic sessions.</li>
165
+ </ul>
166
+ </div>
167
+ <template #footer>
168
+ <button class="p-1 opacity-60 hover:opacity-100">Copy</button>
169
+ </template>
170
+ </CkAgentMessage>
171
+ `,
172
+ }),
173
+ parameters: { docs: { source: { code: withRichContentTemplateSource } } },
174
+ };
175
+
176
+ /**
177
+ * Replaces the default header row with a custom title/metadata block.
178
+ * Use to label the assistant (agent name, version, model) above the message body.
179
+ */
180
+ export const WithCustomHeader: Story = {
181
+ render: () => ({
182
+ components: { CkAgentMessage },
183
+ template: `
184
+ <CkAgentMessage>
185
+ <template #icon>
186
+ <div class="bg-core-bg-tertiary flex size-6 items-center justify-center rounded-full text-xs">
187
+ AI
188
+ </div>
189
+ </template>
190
+ <template #header>
191
+ <span>Custom Agent</span>
192
+ <span class="text-core-content-quaternary ml-2 text-xs font-normal">v2.1</span>
193
+ </template>
194
+ <p>Hello! How can I assist you today?</p>
195
+ </CkAgentMessage>
196
+ `,
197
+ }),
198
+ parameters: { docs: { source: { code: withCustomHeaderTemplateSource } } },
199
+ };
200
+
201
+ /**
202
+ * Omits the icon slot. Use for minimalist conversations or systems where
203
+ * the assistant identity is conveyed elsewhere.
204
+ */
205
+ export const WithoutIcon: Story = {
206
+ render: () => ({
207
+ components: { CkAgentMessage },
208
+ template: `
209
+ <CkAgentMessage>
210
+ <p>A message from an agent without a custom icon.</p>
211
+ </CkAgentMessage>
212
+ `,
213
+ }),
214
+ parameters: { docs: { source: { code: withoutIconTemplateSource } } },
215
+ };
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ defineOptions({ name: 'CkAgentMessage' });
3
+ </script>
4
+
5
+ <template>
6
+ <div class="flex w-full items-start gap-2">
7
+ <div
8
+ v-if="$slots.icon"
9
+ class="flex flex-shrink-0 items-center justify-center"
10
+ >
11
+ <slot name="icon" />
12
+ </div>
13
+ <div class="text-core-content-primary flex min-w-0 flex-1 flex-col gap-2">
14
+ <span v-if="$slots.header" class="text-sm font-bold">
15
+ <slot name="header" />
16
+ </span>
17
+ <div>
18
+ <slot />
19
+ </div>
20
+ <div v-if="$slots.footer" class="flex items-center">
21
+ <slot name="footer" />
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as CkAgentMessage } from './CkAgentMessage.vue';
2
+ export type * from './types';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Layout for a single assistant (agent) turn in a conversation. Exposes
3
+ * `icon`, `header`, default content and `footer` slots for full control over
4
+ * each section while keeping consistent spacing and alignment.
5
+ *
6
+ * @category Messages
7
+ * @useCases render assistant reply, AI message layout, conversation turn, streaming message container
8
+ * @keywords agent, assistant, message, bubble, reply, ai, conversation
9
+ * @related CkUserMessage, CkConversation, CkMarkdownRenderer, CkCopyMessageActionButton
10
+ */
11
+ export type CkAgentMessageProps = Record<string, never>;