vanilla-agent 1.20.0 → 1.22.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/README.md +87 -0
- package/dist/index.cjs +24 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +608 -6
- package/dist/index.d.ts +608 -6
- package/dist/index.global.js +44 -44
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/widget.css +467 -5
- package/package.json +1 -1
- package/src/client.ts +215 -1
- package/src/components/launcher.ts +10 -1
- package/src/components/message-bubble.ts +208 -4
- package/src/components/messages.ts +10 -3
- package/src/defaults.ts +32 -0
- package/src/index.ts +20 -4
- package/src/install.ts +69 -7
- package/src/postprocessors.ts +124 -6
- package/src/session.ts +77 -1
- package/src/styles/widget.css +467 -5
- package/src/types.ts +487 -0
- package/src/ui.ts +40 -5
package/src/types.ts
CHANGED
|
@@ -93,6 +93,66 @@ export type AgentWidgetActionEventPayload = {
|
|
|
93
93
|
message: AgentWidgetMessage;
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Feedback event payload for upvote/downvote actions on messages
|
|
98
|
+
*/
|
|
99
|
+
export type AgentWidgetMessageFeedback = {
|
|
100
|
+
type: "upvote" | "downvote";
|
|
101
|
+
messageId: string;
|
|
102
|
+
message: AgentWidgetMessage;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Configuration for message action buttons (copy, upvote, downvote)
|
|
107
|
+
*/
|
|
108
|
+
export type AgentWidgetMessageActionsConfig = {
|
|
109
|
+
/**
|
|
110
|
+
* Enable/disable message actions entirely
|
|
111
|
+
* @default true
|
|
112
|
+
*/
|
|
113
|
+
enabled?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Show copy button
|
|
116
|
+
* @default true
|
|
117
|
+
*/
|
|
118
|
+
showCopy?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Show upvote button
|
|
121
|
+
* @default false (requires backend)
|
|
122
|
+
*/
|
|
123
|
+
showUpvote?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Show downvote button
|
|
126
|
+
* @default false (requires backend)
|
|
127
|
+
*/
|
|
128
|
+
showDownvote?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Visibility mode: 'always' shows buttons always, 'hover' shows on hover only
|
|
131
|
+
* @default 'hover'
|
|
132
|
+
*/
|
|
133
|
+
visibility?: "always" | "hover";
|
|
134
|
+
/**
|
|
135
|
+
* Horizontal alignment of action buttons
|
|
136
|
+
* @default 'right'
|
|
137
|
+
*/
|
|
138
|
+
align?: "left" | "center" | "right";
|
|
139
|
+
/**
|
|
140
|
+
* Layout style for action buttons
|
|
141
|
+
* - 'pill-inside': Compact floating pill around just the buttons (default for hover)
|
|
142
|
+
* - 'row-inside': Full-width row at the bottom of the message
|
|
143
|
+
* @default 'pill-inside'
|
|
144
|
+
*/
|
|
145
|
+
layout?: "pill-inside" | "row-inside";
|
|
146
|
+
/**
|
|
147
|
+
* Callback when user submits feedback (upvote/downvote)
|
|
148
|
+
*/
|
|
149
|
+
onFeedback?: (feedback: AgentWidgetMessageFeedback) => void;
|
|
150
|
+
/**
|
|
151
|
+
* Callback when user copies a message
|
|
152
|
+
*/
|
|
153
|
+
onCopy?: (message: AgentWidgetMessage) => void;
|
|
154
|
+
};
|
|
155
|
+
|
|
96
156
|
export type AgentWidgetStateEvent = {
|
|
97
157
|
open: boolean;
|
|
98
158
|
source: "user" | "auto" | "api" | "system";
|
|
@@ -114,6 +174,8 @@ export type AgentWidgetControllerEventMap = {
|
|
|
114
174
|
"widget:opened": AgentWidgetStateEvent;
|
|
115
175
|
"widget:closed": AgentWidgetStateEvent;
|
|
116
176
|
"widget:state": AgentWidgetStateSnapshot;
|
|
177
|
+
"message:feedback": AgentWidgetMessageFeedback;
|
|
178
|
+
"message:copy": AgentWidgetMessage;
|
|
117
179
|
};
|
|
118
180
|
|
|
119
181
|
export type AgentWidgetFeatureFlags = {
|
|
@@ -250,6 +312,18 @@ export type AgentWidgetLauncherConfig = {
|
|
|
250
312
|
closeButtonTooltipText?: string;
|
|
251
313
|
closeButtonShowTooltip?: boolean;
|
|
252
314
|
clearChat?: AgentWidgetClearChatConfig;
|
|
315
|
+
/**
|
|
316
|
+
* Border style for the launcher button.
|
|
317
|
+
* @example "1px solid #e5e7eb" | "2px solid #3b82f6" | "none"
|
|
318
|
+
* @default "1px solid #e5e7eb"
|
|
319
|
+
*/
|
|
320
|
+
border?: string;
|
|
321
|
+
/**
|
|
322
|
+
* Box shadow for the launcher button.
|
|
323
|
+
* @example "0 10px 15px -3px rgba(0,0,0,0.1)" | "none"
|
|
324
|
+
* @default "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)"
|
|
325
|
+
*/
|
|
326
|
+
shadow?: string;
|
|
253
327
|
};
|
|
254
328
|
|
|
255
329
|
export type AgentWidgetSendButtonConfig = {
|
|
@@ -442,6 +516,62 @@ export type AgentWidgetCustomFetch = (
|
|
|
442
516
|
*/
|
|
443
517
|
export type AgentWidgetHeadersFunction = () => Record<string, string> | Promise<Record<string, string>>;
|
|
444
518
|
|
|
519
|
+
// ============================================================================
|
|
520
|
+
// Client Token Types
|
|
521
|
+
// ============================================================================
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Session information returned after client token initialization.
|
|
525
|
+
* Contains session ID, expiry time, flow info, and config from the server.
|
|
526
|
+
*/
|
|
527
|
+
export type ClientSession = {
|
|
528
|
+
/** Unique session identifier */
|
|
529
|
+
sessionId: string;
|
|
530
|
+
/** When the session expires */
|
|
531
|
+
expiresAt: Date;
|
|
532
|
+
/** Flow information */
|
|
533
|
+
flow: {
|
|
534
|
+
id: string;
|
|
535
|
+
name: string;
|
|
536
|
+
description: string | null;
|
|
537
|
+
};
|
|
538
|
+
/** Configuration from the server */
|
|
539
|
+
config: {
|
|
540
|
+
welcomeMessage: string | null;
|
|
541
|
+
placeholder: string;
|
|
542
|
+
theme: Record<string, unknown> | null;
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Raw API response from /v1/client/init endpoint
|
|
548
|
+
*/
|
|
549
|
+
export type ClientInitResponse = {
|
|
550
|
+
session_id: string;
|
|
551
|
+
expires_at: string;
|
|
552
|
+
flow: {
|
|
553
|
+
id: string;
|
|
554
|
+
name: string;
|
|
555
|
+
description: string | null;
|
|
556
|
+
};
|
|
557
|
+
config: {
|
|
558
|
+
welcome_message: string | null;
|
|
559
|
+
placeholder: string;
|
|
560
|
+
theme: Record<string, unknown> | null;
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Request payload for /v1/client/chat endpoint
|
|
566
|
+
*/
|
|
567
|
+
export type ClientChatRequest = {
|
|
568
|
+
session_id: string;
|
|
569
|
+
messages: Array<{
|
|
570
|
+
role: 'user' | 'assistant' | 'system';
|
|
571
|
+
content: string;
|
|
572
|
+
}>;
|
|
573
|
+
};
|
|
574
|
+
|
|
445
575
|
// ============================================================================
|
|
446
576
|
// Layout Configuration Types
|
|
447
577
|
// ============================================================================
|
|
@@ -610,9 +740,315 @@ export type AgentWidgetLayoutConfig = {
|
|
|
610
740
|
slots?: Partial<Record<WidgetLayoutSlot, SlotRenderer>>;
|
|
611
741
|
};
|
|
612
742
|
|
|
743
|
+
// ============================================================================
|
|
744
|
+
// Markdown Configuration Types
|
|
745
|
+
// ============================================================================
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Token types for marked renderer methods
|
|
749
|
+
*/
|
|
750
|
+
export type AgentWidgetMarkdownHeadingToken = {
|
|
751
|
+
type: "heading";
|
|
752
|
+
raw: string;
|
|
753
|
+
depth: 1 | 2 | 3 | 4 | 5 | 6;
|
|
754
|
+
text: string;
|
|
755
|
+
tokens: unknown[];
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
export type AgentWidgetMarkdownCodeToken = {
|
|
759
|
+
type: "code";
|
|
760
|
+
raw: string;
|
|
761
|
+
text: string;
|
|
762
|
+
lang?: string;
|
|
763
|
+
escaped?: boolean;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
export type AgentWidgetMarkdownBlockquoteToken = {
|
|
767
|
+
type: "blockquote";
|
|
768
|
+
raw: string;
|
|
769
|
+
text: string;
|
|
770
|
+
tokens: unknown[];
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
export type AgentWidgetMarkdownTableToken = {
|
|
774
|
+
type: "table";
|
|
775
|
+
raw: string;
|
|
776
|
+
header: Array<{ text: string; tokens: unknown[] }>;
|
|
777
|
+
rows: Array<Array<{ text: string; tokens: unknown[] }>>;
|
|
778
|
+
align: Array<"left" | "center" | "right" | null>;
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
export type AgentWidgetMarkdownLinkToken = {
|
|
782
|
+
type: "link";
|
|
783
|
+
raw: string;
|
|
784
|
+
href: string;
|
|
785
|
+
title: string | null;
|
|
786
|
+
text: string;
|
|
787
|
+
tokens: unknown[];
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
export type AgentWidgetMarkdownImageToken = {
|
|
791
|
+
type: "image";
|
|
792
|
+
raw: string;
|
|
793
|
+
href: string;
|
|
794
|
+
title: string | null;
|
|
795
|
+
text: string;
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
export type AgentWidgetMarkdownListToken = {
|
|
799
|
+
type: "list";
|
|
800
|
+
raw: string;
|
|
801
|
+
ordered: boolean;
|
|
802
|
+
start: number | "";
|
|
803
|
+
loose: boolean;
|
|
804
|
+
items: unknown[];
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
export type AgentWidgetMarkdownListItemToken = {
|
|
808
|
+
type: "list_item";
|
|
809
|
+
raw: string;
|
|
810
|
+
task: boolean;
|
|
811
|
+
checked?: boolean;
|
|
812
|
+
loose: boolean;
|
|
813
|
+
text: string;
|
|
814
|
+
tokens: unknown[];
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
export type AgentWidgetMarkdownParagraphToken = {
|
|
818
|
+
type: "paragraph";
|
|
819
|
+
raw: string;
|
|
820
|
+
text: string;
|
|
821
|
+
tokens: unknown[];
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
export type AgentWidgetMarkdownCodespanToken = {
|
|
825
|
+
type: "codespan";
|
|
826
|
+
raw: string;
|
|
827
|
+
text: string;
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
export type AgentWidgetMarkdownStrongToken = {
|
|
831
|
+
type: "strong";
|
|
832
|
+
raw: string;
|
|
833
|
+
text: string;
|
|
834
|
+
tokens: unknown[];
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
export type AgentWidgetMarkdownEmToken = {
|
|
838
|
+
type: "em";
|
|
839
|
+
raw: string;
|
|
840
|
+
text: string;
|
|
841
|
+
tokens: unknown[];
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Custom renderer overrides for markdown elements.
|
|
846
|
+
* Each method receives the token and should return an HTML string.
|
|
847
|
+
* Return `false` to use the default renderer.
|
|
848
|
+
*
|
|
849
|
+
* @example
|
|
850
|
+
* ```typescript
|
|
851
|
+
* renderer: {
|
|
852
|
+
* heading(token) {
|
|
853
|
+
* return `<h${token.depth} class="custom-heading">${token.text}</h${token.depth}>`;
|
|
854
|
+
* },
|
|
855
|
+
* link(token) {
|
|
856
|
+
* return `<a href="${token.href}" target="_blank" rel="noopener">${token.text}</a>`;
|
|
857
|
+
* }
|
|
858
|
+
* }
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
export type AgentWidgetMarkdownRendererOverrides = {
|
|
862
|
+
/** Override heading rendering (h1-h6) */
|
|
863
|
+
heading?: (token: AgentWidgetMarkdownHeadingToken) => string | false;
|
|
864
|
+
/** Override code block rendering */
|
|
865
|
+
code?: (token: AgentWidgetMarkdownCodeToken) => string | false;
|
|
866
|
+
/** Override blockquote rendering */
|
|
867
|
+
blockquote?: (token: AgentWidgetMarkdownBlockquoteToken) => string | false;
|
|
868
|
+
/** Override table rendering */
|
|
869
|
+
table?: (token: AgentWidgetMarkdownTableToken) => string | false;
|
|
870
|
+
/** Override link rendering */
|
|
871
|
+
link?: (token: AgentWidgetMarkdownLinkToken) => string | false;
|
|
872
|
+
/** Override image rendering */
|
|
873
|
+
image?: (token: AgentWidgetMarkdownImageToken) => string | false;
|
|
874
|
+
/** Override list rendering (ul/ol) */
|
|
875
|
+
list?: (token: AgentWidgetMarkdownListToken) => string | false;
|
|
876
|
+
/** Override list item rendering */
|
|
877
|
+
listitem?: (token: AgentWidgetMarkdownListItemToken) => string | false;
|
|
878
|
+
/** Override paragraph rendering */
|
|
879
|
+
paragraph?: (token: AgentWidgetMarkdownParagraphToken) => string | false;
|
|
880
|
+
/** Override inline code rendering */
|
|
881
|
+
codespan?: (token: AgentWidgetMarkdownCodespanToken) => string | false;
|
|
882
|
+
/** Override strong/bold rendering */
|
|
883
|
+
strong?: (token: AgentWidgetMarkdownStrongToken) => string | false;
|
|
884
|
+
/** Override emphasis/italic rendering */
|
|
885
|
+
em?: (token: AgentWidgetMarkdownEmToken) => string | false;
|
|
886
|
+
/** Override horizontal rule rendering */
|
|
887
|
+
hr?: () => string | false;
|
|
888
|
+
/** Override line break rendering */
|
|
889
|
+
br?: () => string | false;
|
|
890
|
+
/** Override deleted/strikethrough rendering */
|
|
891
|
+
del?: (token: { type: "del"; raw: string; text: string; tokens: unknown[] }) => string | false;
|
|
892
|
+
/** Override checkbox rendering (in task lists) */
|
|
893
|
+
checkbox?: (token: { checked: boolean }) => string | false;
|
|
894
|
+
/** Override HTML passthrough */
|
|
895
|
+
html?: (token: { type: "html"; raw: string; text: string }) => string | false;
|
|
896
|
+
/** Override text rendering */
|
|
897
|
+
text?: (token: { type: "text"; raw: string; text: string }) => string | false;
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Markdown parsing options (subset of marked options)
|
|
902
|
+
*/
|
|
903
|
+
export type AgentWidgetMarkdownOptions = {
|
|
904
|
+
/**
|
|
905
|
+
* Enable GitHub Flavored Markdown (tables, strikethrough, autolinks).
|
|
906
|
+
* @default true
|
|
907
|
+
*/
|
|
908
|
+
gfm?: boolean;
|
|
909
|
+
/**
|
|
910
|
+
* Convert \n in paragraphs into <br>.
|
|
911
|
+
* @default true
|
|
912
|
+
*/
|
|
913
|
+
breaks?: boolean;
|
|
914
|
+
/**
|
|
915
|
+
* Conform to original markdown.pl as much as possible.
|
|
916
|
+
* @default false
|
|
917
|
+
*/
|
|
918
|
+
pedantic?: boolean;
|
|
919
|
+
/**
|
|
920
|
+
* Add id attributes to headings.
|
|
921
|
+
* @default false
|
|
922
|
+
*/
|
|
923
|
+
headerIds?: boolean;
|
|
924
|
+
/**
|
|
925
|
+
* Prefix for heading id attributes.
|
|
926
|
+
* @default ""
|
|
927
|
+
*/
|
|
928
|
+
headerPrefix?: string;
|
|
929
|
+
/**
|
|
930
|
+
* Mangle email addresses for spam protection.
|
|
931
|
+
* @default true
|
|
932
|
+
*/
|
|
933
|
+
mangle?: boolean;
|
|
934
|
+
/**
|
|
935
|
+
* Silent mode - don't throw on parse errors.
|
|
936
|
+
* @default false
|
|
937
|
+
*/
|
|
938
|
+
silent?: boolean;
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Markdown configuration for customizing how markdown is rendered in chat messages.
|
|
943
|
+
* Provides three levels of control:
|
|
944
|
+
*
|
|
945
|
+
* 1. **CSS Variables** - Override styles via `--cw-md-*` CSS custom properties
|
|
946
|
+
* 2. **Parsing Options** - Configure marked behavior via `options`
|
|
947
|
+
* 3. **Custom Renderers** - Full control via `renderer` overrides
|
|
948
|
+
*
|
|
949
|
+
* @example
|
|
950
|
+
* ```typescript
|
|
951
|
+
* // Level 2: Configure parsing options
|
|
952
|
+
* config: {
|
|
953
|
+
* markdown: {
|
|
954
|
+
* options: {
|
|
955
|
+
* gfm: true,
|
|
956
|
+
* breaks: true,
|
|
957
|
+
* headerIds: true
|
|
958
|
+
* }
|
|
959
|
+
* }
|
|
960
|
+
* }
|
|
961
|
+
* ```
|
|
962
|
+
*
|
|
963
|
+
* @example
|
|
964
|
+
* ```typescript
|
|
965
|
+
* // Level 3: Custom renderers
|
|
966
|
+
* config: {
|
|
967
|
+
* markdown: {
|
|
968
|
+
* renderer: {
|
|
969
|
+
* heading(token) {
|
|
970
|
+
* return `<h${token.depth} class="custom-h${token.depth}">${token.text}</h${token.depth}>`;
|
|
971
|
+
* },
|
|
972
|
+
* link(token) {
|
|
973
|
+
* return `<a href="${token.href}" target="_blank">${token.text}</a>`;
|
|
974
|
+
* },
|
|
975
|
+
* table(token) {
|
|
976
|
+
* // Wrap tables in a scrollable container
|
|
977
|
+
* return `<div class="table-scroll">${this.parser.parse(token.tokens)}</div>`;
|
|
978
|
+
* }
|
|
979
|
+
* }
|
|
980
|
+
* }
|
|
981
|
+
* }
|
|
982
|
+
* ```
|
|
983
|
+
*/
|
|
984
|
+
export type AgentWidgetMarkdownConfig = {
|
|
985
|
+
/**
|
|
986
|
+
* Markdown parsing options.
|
|
987
|
+
* These are passed directly to the marked parser.
|
|
988
|
+
*/
|
|
989
|
+
options?: AgentWidgetMarkdownOptions;
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Custom renderer overrides for specific markdown elements.
|
|
993
|
+
* Each method receives a token object and should return an HTML string.
|
|
994
|
+
* Return `false` to fall back to the default renderer.
|
|
995
|
+
*/
|
|
996
|
+
renderer?: AgentWidgetMarkdownRendererOverrides;
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Disable default markdown CSS styles.
|
|
1000
|
+
* When true, the widget won't apply any default styles to markdown elements,
|
|
1001
|
+
* allowing you to provide your own CSS.
|
|
1002
|
+
*
|
|
1003
|
+
* @default false
|
|
1004
|
+
*/
|
|
1005
|
+
disableDefaultStyles?: boolean;
|
|
1006
|
+
};
|
|
1007
|
+
|
|
613
1008
|
export type AgentWidgetConfig = {
|
|
614
1009
|
apiUrl?: string;
|
|
615
1010
|
flowId?: string;
|
|
1011
|
+
/**
|
|
1012
|
+
* Client token for direct browser-to-API communication.
|
|
1013
|
+
* When set, the widget uses /v1/client/* endpoints instead of /v1/dispatch.
|
|
1014
|
+
* Mutually exclusive with apiKey/headers authentication.
|
|
1015
|
+
*
|
|
1016
|
+
* @example
|
|
1017
|
+
* ```typescript
|
|
1018
|
+
* config: {
|
|
1019
|
+
* clientToken: 'ct_live_flow01k7_a8b9c0d1e2f3g4h5i6j7k8l9'
|
|
1020
|
+
* }
|
|
1021
|
+
* ```
|
|
1022
|
+
*/
|
|
1023
|
+
clientToken?: string;
|
|
1024
|
+
/**
|
|
1025
|
+
* Callback when session is initialized (client token mode only).
|
|
1026
|
+
* Receives session info including expiry time.
|
|
1027
|
+
*
|
|
1028
|
+
* @example
|
|
1029
|
+
* ```typescript
|
|
1030
|
+
* config: {
|
|
1031
|
+
* onSessionInit: (session) => {
|
|
1032
|
+
* console.log('Session started:', session.sessionId);
|
|
1033
|
+
* }
|
|
1034
|
+
* }
|
|
1035
|
+
* ```
|
|
1036
|
+
*/
|
|
1037
|
+
onSessionInit?: (session: ClientSession) => void;
|
|
1038
|
+
/**
|
|
1039
|
+
* Callback when session expires or errors (client token mode only).
|
|
1040
|
+
* Widget should prompt user to refresh.
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```typescript
|
|
1044
|
+
* config: {
|
|
1045
|
+
* onSessionExpired: () => {
|
|
1046
|
+
* alert('Your session has expired. Please refresh the page.');
|
|
1047
|
+
* }
|
|
1048
|
+
* }
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
1051
|
+
onSessionExpired?: () => void;
|
|
616
1052
|
/**
|
|
617
1053
|
* Static headers to include with each request.
|
|
618
1054
|
* For dynamic headers (e.g., auth tokens), use `getHeaders` instead.
|
|
@@ -819,6 +1255,57 @@ export type AgentWidgetConfig = {
|
|
|
819
1255
|
* ```
|
|
820
1256
|
*/
|
|
821
1257
|
layout?: AgentWidgetLayoutConfig;
|
|
1258
|
+
|
|
1259
|
+
/**
|
|
1260
|
+
* Markdown rendering configuration.
|
|
1261
|
+
* Customize how markdown is parsed and rendered in chat messages.
|
|
1262
|
+
*
|
|
1263
|
+
* Override methods:
|
|
1264
|
+
* 1. **CSS Variables** - Override `--cw-md-*` variables in your stylesheet
|
|
1265
|
+
* 2. **Options** - Configure marked parser behavior
|
|
1266
|
+
* 3. **Renderers** - Custom rendering functions for specific elements
|
|
1267
|
+
* 4. **postprocessMessage** - Complete control over message transformation
|
|
1268
|
+
*
|
|
1269
|
+
* @example
|
|
1270
|
+
* ```typescript
|
|
1271
|
+
* config: {
|
|
1272
|
+
* markdown: {
|
|
1273
|
+
* options: { breaks: true, gfm: true },
|
|
1274
|
+
* renderer: {
|
|
1275
|
+
* link(token) {
|
|
1276
|
+
* return `<a href="${token.href}" target="_blank">${token.text}</a>`;
|
|
1277
|
+
* }
|
|
1278
|
+
* }
|
|
1279
|
+
* }
|
|
1280
|
+
* }
|
|
1281
|
+
* ```
|
|
1282
|
+
*/
|
|
1283
|
+
markdown?: AgentWidgetMarkdownConfig;
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* Configuration for message action buttons (copy, upvote, downvote).
|
|
1287
|
+
* Shows action buttons on assistant messages for user feedback.
|
|
1288
|
+
*
|
|
1289
|
+
* @example
|
|
1290
|
+
* ```typescript
|
|
1291
|
+
* config: {
|
|
1292
|
+
* messageActions: {
|
|
1293
|
+
* enabled: true,
|
|
1294
|
+
* showCopy: true,
|
|
1295
|
+
* showUpvote: true,
|
|
1296
|
+
* showDownvote: true,
|
|
1297
|
+
* visibility: 'hover',
|
|
1298
|
+
* onFeedback: (feedback) => {
|
|
1299
|
+
* console.log('Feedback:', feedback.type, feedback.messageId);
|
|
1300
|
+
* },
|
|
1301
|
+
* onCopy: (message) => {
|
|
1302
|
+
* console.log('Copied message:', message.id);
|
|
1303
|
+
* }
|
|
1304
|
+
* }
|
|
1305
|
+
* }
|
|
1306
|
+
* ```
|
|
1307
|
+
*/
|
|
1308
|
+
messageActions?: AgentWidgetMessageActionsConfig;
|
|
822
1309
|
};
|
|
823
1310
|
|
|
824
1311
|
export type AgentWidgetMessageRole = "user" | "assistant" | "system";
|
package/src/ui.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { escapeHtml } from "./postprocessors";
|
|
1
|
+
import { escapeHtml, createMarkdownProcessorFromConfig } from "./postprocessors";
|
|
2
2
|
import { AgentWidgetSession, AgentWidgetSessionStatus } from "./session";
|
|
3
3
|
import {
|
|
4
4
|
AgentWidgetConfig,
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
AgentWidgetStateEvent,
|
|
12
12
|
AgentWidgetStateSnapshot,
|
|
13
13
|
WidgetLayoutSlot,
|
|
14
|
-
SlotRenderer
|
|
14
|
+
SlotRenderer,
|
|
15
|
+
AgentWidgetMessageFeedback
|
|
15
16
|
} from "./types";
|
|
16
17
|
import { applyThemeVariables } from "./utils/theme";
|
|
17
18
|
import { renderLucideIcon } from "./utils/icons";
|
|
@@ -21,7 +22,7 @@ import { createLauncherButton } from "./components/launcher";
|
|
|
21
22
|
import { createWrapper, buildPanel, buildHeader, buildComposer, attachHeaderToContainer } from "./components/panel";
|
|
22
23
|
import { positionMap } from "./utils/positioning";
|
|
23
24
|
import type { HeaderElements, ComposerElements } from "./components/panel";
|
|
24
|
-
import { MessageTransform } from "./components/message-bubble";
|
|
25
|
+
import { MessageTransform, MessageActionCallbacks } from "./components/message-bubble";
|
|
25
26
|
import { createStandardBubble, createTypingIndicator } from "./components/message-bubble";
|
|
26
27
|
import { createReasoningBubble } from "./components/reasoning-bubble";
|
|
27
28
|
import { createToolBubble } from "./components/tool-bubble";
|
|
@@ -96,6 +97,12 @@ const buildPostprocessor = (
|
|
|
96
97
|
cfg: AgentWidgetConfig | undefined,
|
|
97
98
|
actionManager?: ReturnType<typeof createActionManager>
|
|
98
99
|
): MessageTransform => {
|
|
100
|
+
// Create markdown processor from config if markdown config is provided
|
|
101
|
+
// This allows users to enable markdown rendering via config.markdown
|
|
102
|
+
const markdownProcessor = cfg?.markdown
|
|
103
|
+
? createMarkdownProcessorFromConfig(cfg.markdown)
|
|
104
|
+
: null;
|
|
105
|
+
|
|
99
106
|
return (context) => {
|
|
100
107
|
let nextText = context.text ?? "";
|
|
101
108
|
const rawPayload = context.message.rawContent ?? null;
|
|
@@ -116,6 +123,7 @@ const buildPostprocessor = (
|
|
|
116
123
|
}
|
|
117
124
|
}
|
|
118
125
|
|
|
126
|
+
// Priority: postprocessMessage > markdown config > escapeHtml
|
|
119
127
|
if (cfg?.postprocessMessage) {
|
|
120
128
|
return cfg.postprocessMessage({
|
|
121
129
|
...context,
|
|
@@ -124,6 +132,11 @@ const buildPostprocessor = (
|
|
|
124
132
|
});
|
|
125
133
|
}
|
|
126
134
|
|
|
135
|
+
// Use markdown processor if markdown config is provided
|
|
136
|
+
if (markdownProcessor) {
|
|
137
|
+
return markdownProcessor(nextText);
|
|
138
|
+
}
|
|
139
|
+
|
|
127
140
|
return escapeHtml(nextText);
|
|
128
141
|
};
|
|
129
142
|
};
|
|
@@ -216,6 +229,16 @@ export const createAgentExperience = (
|
|
|
216
229
|
let showReasoning = config.features?.showReasoning ?? true;
|
|
217
230
|
let showToolCalls = config.features?.showToolCalls ?? true;
|
|
218
231
|
|
|
232
|
+
// Create message action callbacks that emit events
|
|
233
|
+
const messageActionCallbacks: MessageActionCallbacks = {
|
|
234
|
+
onCopy: (message: AgentWidgetMessage) => {
|
|
235
|
+
eventBus.emit("message:copy", message);
|
|
236
|
+
},
|
|
237
|
+
onFeedback: (feedback: AgentWidgetMessageFeedback) => {
|
|
238
|
+
eventBus.emit("message:feedback", feedback);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
219
242
|
// Get status indicator config
|
|
220
243
|
const statusConfig = config.statusIndicator ?? {};
|
|
221
244
|
const getStatusText = (status: AgentWidgetSessionStatus): string => {
|
|
@@ -865,7 +888,13 @@ export const createAgentExperience = (
|
|
|
865
888
|
bubble = matchingPlugin.renderMessage({
|
|
866
889
|
message,
|
|
867
890
|
defaultRenderer: () => {
|
|
868
|
-
const b = createStandardBubble(
|
|
891
|
+
const b = createStandardBubble(
|
|
892
|
+
message,
|
|
893
|
+
transform,
|
|
894
|
+
messageLayoutConfig,
|
|
895
|
+
config.messageActions,
|
|
896
|
+
messageActionCallbacks
|
|
897
|
+
);
|
|
869
898
|
if (message.role !== "user") {
|
|
870
899
|
enhanceWithForms(b, message, config, session);
|
|
871
900
|
}
|
|
@@ -945,7 +974,13 @@ export const createAgentExperience = (
|
|
|
945
974
|
streaming: Boolean(message.streaming)
|
|
946
975
|
});
|
|
947
976
|
} else {
|
|
948
|
-
bubble = createStandardBubble(
|
|
977
|
+
bubble = createStandardBubble(
|
|
978
|
+
message,
|
|
979
|
+
transform,
|
|
980
|
+
messageLayoutConfig,
|
|
981
|
+
config.messageActions,
|
|
982
|
+
messageActionCallbacks
|
|
983
|
+
);
|
|
949
984
|
}
|
|
950
985
|
if (message.role !== "user" && bubble) {
|
|
951
986
|
enhanceWithForms(bubble, message, config, session);
|