@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.
- package/dist/{CkInput.vue_vue_type_script_setup_true_lang-744ZHsQU.js → CkInput.vue_vue_type_script_setup_true_lang-DpYyyCgU.js} +23 -68
- package/dist/components/base/CkHistoryItem/CkHistoryItem.vue.d.ts +3 -4
- package/dist/components/base/CkHistoryItem/CkHistoryItem.vue.d.ts.map +1 -1
- package/dist/components/base/CkHistoryItem/types.d.ts +3 -2
- package/dist/components/base/CkHistoryItem/types.d.ts.map +1 -1
- package/dist/components/base/CkPromptStopButton/CkPromptStopButton.vue.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -5
- package/src/components/base/CkAgentMessage/CkAgentMessage.spec.ts +91 -0
- package/src/components/base/CkAgentMessage/CkAgentMessage.stories.ts +215 -0
- package/src/components/base/CkAgentMessage/CkAgentMessage.vue +25 -0
- package/src/components/base/CkAgentMessage/index.ts +2 -0
- package/src/components/base/CkAgentMessage/types.ts +11 -0
- package/src/components/base/CkConversationLayout/CkConversationLayout.spec.ts +129 -0
- package/src/components/base/CkConversationLayout/CkConversationLayout.stories.ts +251 -0
- package/src/components/base/CkConversationLayout/CkConversationLayout.vue +206 -0
- package/src/components/base/CkConversationLayout/index.ts +2 -0
- package/src/components/base/CkConversationLayout/types.ts +18 -0
- package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.spec.ts +89 -0
- package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.stories.ts +70 -0
- package/src/components/base/CkCopyMessageActionButton/CkCopyMessageActionButton.vue +110 -0
- package/src/components/base/CkCopyMessageActionButton/index.ts +2 -0
- package/src/components/base/CkCopyMessageActionButton/types.ts +43 -0
- package/src/components/base/CkHistoryItem/CkHistoryItem.spec.ts +42 -0
- package/src/components/base/CkHistoryItem/CkHistoryItem.stories.ts +230 -0
- package/src/components/base/CkHistoryItem/CkHistoryItem.vue +285 -0
- package/src/components/base/CkHistoryItem/activeIndicator.ts +15 -0
- package/src/components/base/CkHistoryItem/index.ts +2 -0
- package/src/components/base/CkHistoryItem/types.ts +111 -0
- package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.spec.ts +26 -0
- package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.stories.ts +149 -0
- package/src/components/base/CkHistoryWrapper/CkHistoryWrapper.vue +36 -0
- package/src/components/base/CkHistoryWrapper/index.ts +2 -0
- package/src/components/base/CkHistoryWrapper/types.ts +16 -0
- package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.spec.ts +348 -0
- package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.stories.ts +382 -0
- package/src/components/base/CkMarkdownRenderer/CkMarkdownRenderer.vue +89 -0
- package/src/components/base/CkMarkdownRenderer/defaultMarkdownClasses.ts +19 -0
- package/src/components/base/CkMarkdownRenderer/index.ts +5 -0
- package/src/components/base/CkMarkdownRenderer/types.ts +53 -0
- package/src/components/base/CkMessageActionButton/CkMessageActionButton.spec.ts +40 -0
- package/src/components/base/CkMessageActionButton/CkMessageActionButton.stories.ts +56 -0
- package/src/components/base/CkMessageActionButton/CkMessageActionButton.vue +23 -0
- package/src/components/base/CkMessageActionButton/index.ts +2 -0
- package/src/components/base/CkMessageActionButton/types.ts +21 -0
- package/src/components/base/CkPromptActionButton/CkPromptActionButton.spec.ts +52 -0
- package/src/components/base/CkPromptActionButton/CkPromptActionButton.stories.ts +126 -0
- package/src/components/base/CkPromptActionButton/CkPromptActionButton.vue +25 -0
- package/src/components/base/CkPromptActionButton/index.ts +2 -0
- package/src/components/base/CkPromptActionButton/types.ts +32 -0
- package/src/components/base/CkPromptInput/CkPromptInput.spec.ts +181 -0
- package/src/components/base/CkPromptInput/CkPromptInput.stories.ts +224 -0
- package/src/components/base/CkPromptInput/CkPromptInput.vue +104 -0
- package/src/components/base/CkPromptInput/index.ts +2 -0
- package/src/components/base/CkPromptInput/types.ts +39 -0
- package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.spec.ts +40 -0
- package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.stories.ts +103 -0
- package/src/components/base/CkPromptInputDisclaimer/CkPromptInputDisclaimer.vue +16 -0
- package/src/components/base/CkPromptInputDisclaimer/index.ts +2 -0
- package/src/components/base/CkPromptInputDisclaimer/types.ts +17 -0
- package/src/components/base/CkPromptStopButton/CkPromptStopButton.spec.ts +64 -0
- package/src/components/base/CkPromptStopButton/CkPromptStopButton.stories.ts +81 -0
- package/src/components/base/CkPromptStopButton/CkPromptStopButton.vue +27 -0
- package/src/components/base/CkPromptStopButton/index.ts +2 -0
- package/src/components/base/CkPromptStopButton/types.ts +28 -0
- package/src/components/base/CkUserMessage/CkUserMessage.spec.ts +20 -0
- package/src/components/base/CkUserMessage/CkUserMessage.stories.ts +112 -0
- package/src/components/base/CkUserMessage/CkUserMessage.vue +19 -0
- package/src/components/base/CkUserMessage/index.ts +2 -0
- package/src/components/base/CkUserMessage/types.ts +14 -0
- package/src/components/base/icons/CkSendIcon.vue +22 -0
- package/src/components/base/icons/CkStopIcon.vue +18 -0
- package/src/components/base/icons/index.ts +2 -0
- package/src/components/base/index.ts +21 -0
- package/src/components/composed/CkConversation/CkConversation.spec.ts +439 -0
- package/src/components/composed/CkConversation/CkConversation.stories.ts +642 -0
- package/src/components/composed/CkConversation/CkConversation.vue +146 -0
- package/src/components/composed/CkConversation/index.ts +2 -0
- package/src/components/composed/CkConversation/types.ts +37 -0
- package/src/components/composed/CkHistory/CkHistory.spec.ts +327 -0
- package/src/components/composed/CkHistory/CkHistory.stories.ts +373 -0
- package/src/components/composed/CkHistory/CkHistory.vue +126 -0
- package/src/components/composed/CkHistory/index.ts +2 -0
- package/src/components/composed/CkHistory/types.ts +72 -0
- package/src/components/composed/CkInput/CkInput.spec.ts +191 -0
- package/src/components/composed/CkInput/CkInput.stories.ts +438 -0
- package/src/components/composed/CkInput/CkInput.vue +104 -0
- package/src/components/composed/CkInput/index.ts +2 -0
- package/src/components/composed/CkInput/types.ts +60 -0
- package/src/components/composed/index.ts +5 -0
- package/src/components/index.ts +34 -0
- package/src/composables/index.ts +9 -0
- package/src/composables/types.ts +36 -0
- package/src/composables/useChat.ts +18 -0
- package/src/composables/useConversations.spec.ts +557 -0
- package/src/composables/useConversations.ts +321 -0
- package/src/handlers/index.ts +9 -0
- package/src/handlers/useChatKitLabels.spec.ts +290 -0
- package/src/handlers/useChatKitLabels.ts +96 -0
- package/src/handlers/useMarkdownParser.spec.ts +112 -0
- package/src/handlers/useMarkdownParser.ts +47 -0
- package/src/handlers/useMessageHandler.spec.ts +535 -0
- package/src/handlers/useMessageHandler.ts +138 -0
- package/src/helpers/conversationTree.spec.ts +423 -0
- package/src/helpers/conversationTree.ts +117 -0
- package/src/helpers/generateId.ts +5 -0
- package/src/helpers/index.ts +4 -0
- package/src/helpers/secondsToDate.ts +7 -0
- package/src/helpers/toError.ts +8 -0
- package/src/index.ts +79 -0
- package/src/services/ChatService.ts +60 -0
- package/src/services/MockChatService.ts +47 -0
- package/src/services/index.ts +12 -0
- package/src/services/types.ts +92 -0
- package/src/test-setup.ts +12 -0
- package/src/test-utils/createTextPlugin.ts +9 -0
- 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,
|
|
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,
|
|
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
|
|
516
|
-
// pointer/focus is on the action column so the icon's own
|
|
517
|
-
props.isActive
|
|
518
|
-
|
|
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
|
|
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 {
|
|
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:
|
|
571
|
-
"as-child":
|
|
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(
|
|
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 {
|
|
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<
|
|
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<
|
|
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":"
|
|
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 '
|
|
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
|
|
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,
|
|
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":"
|
|
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"}
|
package/dist/components/index.js
CHANGED
|
@@ -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-
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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,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>;
|