@juspay/svelte-ui-components 2.124.0 → 2.126.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/Chat/Chat.svelte +158 -0
- package/dist/Chat/Chat.svelte.d.ts +4 -0
- package/dist/Chat/controller.svelte.d.ts +24 -0
- package/dist/Chat/controller.svelte.js +190 -0
- package/dist/Chat/properties.d.ts +51 -0
- package/dist/Chat/properties.js +1 -0
- package/dist/Chat/roles.d.ts +2 -0
- package/dist/Chat/roles.js +3 -0
- package/dist/Chat/types.d.ts +45 -0
- package/dist/Chat/types.js +1 -0
- package/dist/ChatBubble/ChatBubble.svelte +419 -0
- package/dist/ChatBubble/ChatBubble.svelte.d.ts +4 -0
- package/dist/ChatBubble/properties.d.ts +43 -0
- package/dist/ChatBubble/properties.js +1 -0
- package/dist/ChatComposer/ChatComposer.svelte +289 -0
- package/dist/ChatComposer/ChatComposer.svelte.d.ts +4 -0
- package/dist/ChatComposer/properties.d.ts +33 -0
- package/dist/ChatComposer/properties.js +1 -0
- package/dist/ChatHeader/ChatHeader.svelte +169 -0
- package/dist/ChatHeader/ChatHeader.svelte.d.ts +4 -0
- package/dist/ChatHeader/properties.d.ts +19 -0
- package/dist/ChatHeader/properties.js +1 -0
- package/dist/ChatMessage/ChatMessage.svelte +330 -0
- package/dist/ChatMessage/ChatMessage.svelte.d.ts +4 -0
- package/dist/ChatMessage/properties.d.ts +29 -0
- package/dist/ChatMessage/properties.js +1 -0
- package/dist/ChatMessageList/ChatMessageList.svelte +181 -0
- package/dist/ChatMessageList/ChatMessageList.svelte.d.ts +4 -0
- package/dist/ChatMessageList/properties.d.ts +22 -0
- package/dist/ChatMessageList/properties.js +1 -0
- package/dist/ChatSuggestions/ChatSuggestions.svelte +46 -0
- package/dist/ChatSuggestions/ChatSuggestions.svelte.d.ts +4 -0
- package/dist/ChatSuggestions/properties.d.ts +16 -0
- package/dist/ChatSuggestions/properties.js +1 -0
- package/dist/ChatToolStatus/ChatToolStatus.svelte +63 -0
- package/dist/ChatToolStatus/ChatToolStatus.svelte.d.ts +4 -0
- package/dist/ChatToolStatus/properties.d.ts +10 -0
- package/dist/ChatToolStatus/properties.js +1 -0
- package/dist/LineChart/LineChart.svelte +36 -15
- package/dist/Resizable/Resizable.svelte +304 -0
- package/dist/Resizable/Resizable.svelte.d.ts +4 -0
- package/dist/Resizable/properties.d.ts +27 -0
- package/dist/Resizable/properties.js +1 -0
- package/dist/Table/Table.svelte +109 -10
- package/dist/Table/properties.d.ts +1 -0
- package/dist/assets/attach.svg +3 -0
- package/dist/assets/chat.svg +3 -0
- package/dist/assets/mic.svg +5 -0
- package/dist/assets/retry.svg +4 -0
- package/dist/assets/send.svg +4 -0
- package/dist/assets/stop.svg +3 -0
- package/dist/assets/thumb-down.svg +4 -0
- package/dist/assets/thumb-up.svg +4 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChatHeader from '../ChatHeader/ChatHeader.svelte';
|
|
3
|
+
import ChatMessageList from '../ChatMessageList/ChatMessageList.svelte';
|
|
4
|
+
import ChatComposer from '../ChatComposer/ChatComposer.svelte';
|
|
5
|
+
import ChatSuggestions from '../ChatSuggestions/ChatSuggestions.svelte';
|
|
6
|
+
import ChatToolStatus from '../ChatToolStatus/ChatToolStatus.svelte';
|
|
7
|
+
import type { ChatProperties } from './properties';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
messages,
|
|
11
|
+
value = $bindable(''),
|
|
12
|
+
title = '',
|
|
13
|
+
subtitle = '',
|
|
14
|
+
image,
|
|
15
|
+
imageAlt = '',
|
|
16
|
+
placeholder = '',
|
|
17
|
+
disabled = false,
|
|
18
|
+
streaming = false,
|
|
19
|
+
recording = false,
|
|
20
|
+
autoscroll = true,
|
|
21
|
+
toolStatus = null,
|
|
22
|
+
suggestions = [],
|
|
23
|
+
attachments = $bindable([]),
|
|
24
|
+
accept = '',
|
|
25
|
+
multiple = false,
|
|
26
|
+
allowCopy = false,
|
|
27
|
+
closeLabel = 'Close',
|
|
28
|
+
showClose,
|
|
29
|
+
headerAvatar,
|
|
30
|
+
headerActions,
|
|
31
|
+
headerContent,
|
|
32
|
+
message,
|
|
33
|
+
messageAttachments,
|
|
34
|
+
empty,
|
|
35
|
+
composerLeading,
|
|
36
|
+
sendIcon,
|
|
37
|
+
stopIcon,
|
|
38
|
+
voiceIcon,
|
|
39
|
+
attachIcon,
|
|
40
|
+
onsend,
|
|
41
|
+
onsuggestion,
|
|
42
|
+
onclose,
|
|
43
|
+
onstop,
|
|
44
|
+
onvoice,
|
|
45
|
+
onattach,
|
|
46
|
+
onretry,
|
|
47
|
+
onfeedback,
|
|
48
|
+
testId,
|
|
49
|
+
classes
|
|
50
|
+
}: ChatProperties = $props();
|
|
51
|
+
|
|
52
|
+
let showHeader = $derived(
|
|
53
|
+
title.length > 0 ||
|
|
54
|
+
subtitle.length > 0 ||
|
|
55
|
+
(typeof image === 'string' && image.length > 0) ||
|
|
56
|
+
typeof onclose === 'function' ||
|
|
57
|
+
typeof headerAvatar === 'function' ||
|
|
58
|
+
typeof headerActions === 'function'
|
|
59
|
+
);
|
|
60
|
+
let showSuggestions = $derived(suggestions.length > 0 && messages.length === 0);
|
|
61
|
+
|
|
62
|
+
function handleSuggestion(suggestionValue: string, index: number): void {
|
|
63
|
+
if (typeof onsuggestion === 'function') {
|
|
64
|
+
onsuggestion(suggestionValue, index);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
onsend?.(suggestionValue, []);
|
|
68
|
+
}
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<section
|
|
72
|
+
class="chat {classes ?? ''}"
|
|
73
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
74
|
+
testID={typeof testId === 'string' ? testId : null}
|
|
75
|
+
>
|
|
76
|
+
{#if showHeader}
|
|
77
|
+
<ChatHeader
|
|
78
|
+
{title}
|
|
79
|
+
{subtitle}
|
|
80
|
+
{image}
|
|
81
|
+
{imageAlt}
|
|
82
|
+
{closeLabel}
|
|
83
|
+
{showClose}
|
|
84
|
+
{onclose}
|
|
85
|
+
avatar={headerAvatar}
|
|
86
|
+
actions={headerActions}
|
|
87
|
+
children={headerContent}
|
|
88
|
+
/>
|
|
89
|
+
{/if}
|
|
90
|
+
|
|
91
|
+
<ChatMessageList
|
|
92
|
+
{messages}
|
|
93
|
+
{autoscroll}
|
|
94
|
+
{message}
|
|
95
|
+
{messageAttachments}
|
|
96
|
+
{empty}
|
|
97
|
+
{allowCopy}
|
|
98
|
+
{onretry}
|
|
99
|
+
{onfeedback}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<div class="footer">
|
|
103
|
+
{#if showSuggestions}
|
|
104
|
+
<ChatSuggestions items={suggestions} {disabled} onselect={handleSuggestion} />
|
|
105
|
+
{/if}
|
|
106
|
+
{#if toolStatus !== null}
|
|
107
|
+
<div class="tool-status"><ChatToolStatus label={toolStatus.label} /></div>
|
|
108
|
+
{/if}
|
|
109
|
+
<ChatComposer
|
|
110
|
+
bind:value
|
|
111
|
+
bind:attachments
|
|
112
|
+
{placeholder}
|
|
113
|
+
{disabled}
|
|
114
|
+
{streaming}
|
|
115
|
+
{recording}
|
|
116
|
+
{accept}
|
|
117
|
+
{multiple}
|
|
118
|
+
onsubmit={onsend}
|
|
119
|
+
{onstop}
|
|
120
|
+
{onvoice}
|
|
121
|
+
{onattach}
|
|
122
|
+
leading={composerLeading}
|
|
123
|
+
{sendIcon}
|
|
124
|
+
{stopIcon}
|
|
125
|
+
{voiceIcon}
|
|
126
|
+
{attachIcon}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
</section>
|
|
130
|
+
|
|
131
|
+
<style>
|
|
132
|
+
.chat {
|
|
133
|
+
box-sizing: border-box;
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: column;
|
|
136
|
+
height: var(--chat-height, 100%);
|
|
137
|
+
width: var(--chat-width, 100%);
|
|
138
|
+
background: var(--chat-background, #ffffff);
|
|
139
|
+
border: var(--chat-border, none);
|
|
140
|
+
border-radius: var(--chat-border-radius, 0);
|
|
141
|
+
overflow: hidden;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.footer {
|
|
145
|
+
box-sizing: border-box;
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
gap: var(--chat-footer-gap, 10px);
|
|
149
|
+
padding: var(--chat-footer-padding, 12px 1.5rem);
|
|
150
|
+
background: var(--chat-footer-background, transparent);
|
|
151
|
+
border-top: var(--chat-footer-border-top, none);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.tool-status {
|
|
155
|
+
display: flex;
|
|
156
|
+
justify-content: var(--chat-tool-status-justify, center);
|
|
157
|
+
}
|
|
158
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ChatControllerOptions, ChatMessageData, ChatToolStatus } from './types';
|
|
2
|
+
export declare class ChatController {
|
|
3
|
+
messages: ChatMessageData[];
|
|
4
|
+
isStreaming: boolean;
|
|
5
|
+
toolStatus: ChatToolStatus | null;
|
|
6
|
+
private readonly transport;
|
|
7
|
+
private readonly typewriter;
|
|
8
|
+
private readonly generateId;
|
|
9
|
+
private abortController;
|
|
10
|
+
private sessionId;
|
|
11
|
+
private revealBuffer;
|
|
12
|
+
private revealTimer;
|
|
13
|
+
constructor(options: ChatControllerOptions);
|
|
14
|
+
send(prompt: string): Promise<void>;
|
|
15
|
+
retry(): Promise<void>;
|
|
16
|
+
private stream;
|
|
17
|
+
stop(): void;
|
|
18
|
+
reset(): void;
|
|
19
|
+
private feed;
|
|
20
|
+
private tick;
|
|
21
|
+
private drain;
|
|
22
|
+
private stopReveal;
|
|
23
|
+
private patchReply;
|
|
24
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { partyOf } from './roles';
|
|
2
|
+
const REVEAL_CHARS_PER_TICK = 2;
|
|
3
|
+
const REVEAL_INTERVAL_MS = 22;
|
|
4
|
+
function prefersReducedMotion() {
|
|
5
|
+
return (typeof window !== 'undefined' &&
|
|
6
|
+
typeof window.matchMedia === 'function' &&
|
|
7
|
+
window.matchMedia('(prefers-reduced-motion: reduce)').matches);
|
|
8
|
+
}
|
|
9
|
+
let idCounter = 0;
|
|
10
|
+
function defaultId() {
|
|
11
|
+
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
12
|
+
return crypto.randomUUID();
|
|
13
|
+
}
|
|
14
|
+
idCounter += 1;
|
|
15
|
+
return `msg-${idCounter}`;
|
|
16
|
+
}
|
|
17
|
+
export class ChatController {
|
|
18
|
+
messages = $state([]);
|
|
19
|
+
isStreaming = $state(false);
|
|
20
|
+
toolStatus = $state(null);
|
|
21
|
+
transport;
|
|
22
|
+
typewriter;
|
|
23
|
+
generateId;
|
|
24
|
+
abortController = null;
|
|
25
|
+
sessionId = null;
|
|
26
|
+
revealBuffer = '';
|
|
27
|
+
revealTimer = null;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.transport = options.transport;
|
|
30
|
+
this.typewriter = options.typewriter ?? false;
|
|
31
|
+
this.generateId = options.generateId ?? defaultId;
|
|
32
|
+
this.messages = options.initialMessages ?? [];
|
|
33
|
+
}
|
|
34
|
+
async send(prompt) {
|
|
35
|
+
const trimmed = prompt.trim();
|
|
36
|
+
if (trimmed.length === 0 || this.isStreaming) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const history = this.messages.slice();
|
|
40
|
+
this.messages.push({
|
|
41
|
+
id: this.generateId(),
|
|
42
|
+
role: 'sender',
|
|
43
|
+
content: trimmed,
|
|
44
|
+
status: 'sent'
|
|
45
|
+
});
|
|
46
|
+
await this.stream(trimmed, history);
|
|
47
|
+
}
|
|
48
|
+
async retry() {
|
|
49
|
+
if (this.isStreaming) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let senderIndex = -1;
|
|
53
|
+
for (let i = this.messages.length - 1; i >= 0; i -= 1) {
|
|
54
|
+
const role = this.messages.at(i)?.role;
|
|
55
|
+
if (typeof role === 'string' && partyOf(role) === 'sender') {
|
|
56
|
+
senderIndex = i;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const senderMessage = this.messages.at(senderIndex);
|
|
61
|
+
if (senderIndex < 0 || typeof senderMessage === 'undefined') {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const history = this.messages.slice(0, senderIndex);
|
|
65
|
+
this.messages = this.messages.slice(0, senderIndex + 1);
|
|
66
|
+
await this.stream(senderMessage.content, history);
|
|
67
|
+
}
|
|
68
|
+
async stream(message, history) {
|
|
69
|
+
this.messages.push({
|
|
70
|
+
id: this.generateId(),
|
|
71
|
+
role: 'responder',
|
|
72
|
+
content: '',
|
|
73
|
+
streaming: true
|
|
74
|
+
});
|
|
75
|
+
this.isStreaming = true;
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
this.abortController = controller;
|
|
78
|
+
try {
|
|
79
|
+
await this.transport({ message, history, sessionId: this.sessionId, signal: controller.signal }, {
|
|
80
|
+
onText: (chunk) => {
|
|
81
|
+
this.toolStatus = null;
|
|
82
|
+
this.feed(chunk);
|
|
83
|
+
},
|
|
84
|
+
onToolStatus: (status) => {
|
|
85
|
+
this.toolStatus = status;
|
|
86
|
+
},
|
|
87
|
+
onAttachment: (attachment) => {
|
|
88
|
+
this.patchReply((reply) => {
|
|
89
|
+
const next = reply.attachments ?? [];
|
|
90
|
+
next.push(attachment);
|
|
91
|
+
reply.attachments = next;
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
onError: (error) => {
|
|
95
|
+
this.patchReply((reply) => {
|
|
96
|
+
reply.status = 'error';
|
|
97
|
+
reply.content =
|
|
98
|
+
reply.content.length > 0 ? `${reply.content}\n\n${error.message}` : error.message;
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
onDone: (meta) => {
|
|
102
|
+
if (typeof meta?.sessionId === 'string') {
|
|
103
|
+
this.sessionId = meta.sessionId;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (!controller.signal.aborted) {
|
|
110
|
+
this.patchReply((reply) => {
|
|
111
|
+
reply.status = 'error';
|
|
112
|
+
reply.content = error instanceof Error ? error.message : 'Something went wrong.';
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
await this.drain();
|
|
117
|
+
this.patchReply((reply) => {
|
|
118
|
+
reply.streaming = false;
|
|
119
|
+
});
|
|
120
|
+
if (this.abortController === controller) {
|
|
121
|
+
this.abortController = null;
|
|
122
|
+
}
|
|
123
|
+
this.isStreaming = false;
|
|
124
|
+
this.toolStatus = null;
|
|
125
|
+
}
|
|
126
|
+
stop() {
|
|
127
|
+
this.abortController?.abort();
|
|
128
|
+
this.abortController = null;
|
|
129
|
+
this.stopReveal();
|
|
130
|
+
this.revealBuffer = '';
|
|
131
|
+
this.patchReply((reply) => {
|
|
132
|
+
reply.streaming = false;
|
|
133
|
+
});
|
|
134
|
+
this.isStreaming = false;
|
|
135
|
+
this.toolStatus = null;
|
|
136
|
+
}
|
|
137
|
+
reset() {
|
|
138
|
+
this.stop();
|
|
139
|
+
this.sessionId = null;
|
|
140
|
+
this.messages = [];
|
|
141
|
+
}
|
|
142
|
+
feed(chunk) {
|
|
143
|
+
if (!this.typewriter || prefersReducedMotion()) {
|
|
144
|
+
this.patchReply((reply) => {
|
|
145
|
+
reply.content += chunk;
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.revealBuffer += chunk;
|
|
150
|
+
if (this.revealTimer === null) {
|
|
151
|
+
this.revealTimer = setInterval(() => this.tick(), REVEAL_INTERVAL_MS);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
tick() {
|
|
155
|
+
if (this.revealBuffer.length === 0) {
|
|
156
|
+
this.stopReveal();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const piece = this.revealBuffer.slice(0, REVEAL_CHARS_PER_TICK);
|
|
160
|
+
this.revealBuffer = this.revealBuffer.slice(piece.length);
|
|
161
|
+
this.patchReply((reply) => {
|
|
162
|
+
reply.content += piece;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
drain() {
|
|
166
|
+
return new Promise((resolve) => {
|
|
167
|
+
const check = () => {
|
|
168
|
+
if (this.revealBuffer.length === 0 && this.revealTimer === null) {
|
|
169
|
+
resolve();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
setTimeout(check, REVEAL_INTERVAL_MS);
|
|
173
|
+
};
|
|
174
|
+
check();
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
stopReveal() {
|
|
178
|
+
if (this.revealTimer !== null) {
|
|
179
|
+
clearInterval(this.revealTimer);
|
|
180
|
+
this.revealTimer = null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
patchReply(mutate) {
|
|
184
|
+
const last = this.messages.at(-1);
|
|
185
|
+
if (typeof last === 'undefined' || partyOf(last.role) !== 'responder') {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
mutate(last);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ChatMessageData, ChatToolStatus } from './types';
|
|
3
|
+
import type { ChatMessageFeedback } from '../ChatMessage/properties';
|
|
4
|
+
import type { ChatSuggestion } from '../ChatSuggestions/properties';
|
|
5
|
+
export type ChatProperties = OptionalChatProperties & ChatEventProperties & MandatoryChatProperties;
|
|
6
|
+
export type MandatoryChatProperties = {
|
|
7
|
+
messages: ChatMessageData[];
|
|
8
|
+
};
|
|
9
|
+
export type OptionalChatProperties = {
|
|
10
|
+
value?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
image?: string;
|
|
14
|
+
imageAlt?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
streaming?: boolean;
|
|
18
|
+
recording?: boolean;
|
|
19
|
+
autoscroll?: boolean;
|
|
20
|
+
toolStatus?: ChatToolStatus | null;
|
|
21
|
+
suggestions?: ChatSuggestion[];
|
|
22
|
+
attachments?: File[];
|
|
23
|
+
accept?: string;
|
|
24
|
+
multiple?: boolean;
|
|
25
|
+
allowCopy?: boolean;
|
|
26
|
+
closeLabel?: string;
|
|
27
|
+
showClose?: boolean;
|
|
28
|
+
headerAvatar?: Snippet;
|
|
29
|
+
headerActions?: Snippet;
|
|
30
|
+
headerContent?: Snippet;
|
|
31
|
+
message?: Snippet<[ChatMessageData]>;
|
|
32
|
+
messageAttachments?: Snippet<[ChatMessageData]>;
|
|
33
|
+
empty?: Snippet;
|
|
34
|
+
composerLeading?: Snippet;
|
|
35
|
+
sendIcon?: Snippet;
|
|
36
|
+
stopIcon?: Snippet;
|
|
37
|
+
voiceIcon?: Snippet;
|
|
38
|
+
attachIcon?: Snippet;
|
|
39
|
+
testId?: string;
|
|
40
|
+
classes?: string;
|
|
41
|
+
};
|
|
42
|
+
export type ChatEventProperties = {
|
|
43
|
+
onsend?: (value: string, attachments: File[]) => void;
|
|
44
|
+
onsuggestion?: (value: string, index: number) => void;
|
|
45
|
+
onclose?: () => void;
|
|
46
|
+
onstop?: () => void;
|
|
47
|
+
onvoice?: () => void;
|
|
48
|
+
onattach?: (files: File[]) => void;
|
|
49
|
+
onretry?: () => void;
|
|
50
|
+
onfeedback?: (value: ChatMessageFeedback, message: ChatMessageData) => void;
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type ChatParty = 'sender' | 'responder';
|
|
2
|
+
export type ChatRole = ChatParty | 'user' | 'assistant' | 'system' | (string & {});
|
|
3
|
+
export type ChatMessageStatus = 'sending' | 'sent' | 'error';
|
|
4
|
+
export type ChatMessageData = {
|
|
5
|
+
id: string;
|
|
6
|
+
role: ChatRole;
|
|
7
|
+
content: string;
|
|
8
|
+
html?: string;
|
|
9
|
+
streaming?: boolean;
|
|
10
|
+
status?: ChatMessageStatus;
|
|
11
|
+
timestamp?: number;
|
|
12
|
+
attachments?: unknown[];
|
|
13
|
+
};
|
|
14
|
+
export type ChatToolStatus = {
|
|
15
|
+
tool?: string;
|
|
16
|
+
label: string;
|
|
17
|
+
state?: 'calling' | 'done';
|
|
18
|
+
};
|
|
19
|
+
export type ChatError = {
|
|
20
|
+
code?: string;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
export type ChatStreamHandlers = {
|
|
24
|
+
onText: (chunk: string) => void;
|
|
25
|
+
onToolStatus?: (status: ChatToolStatus | null) => void;
|
|
26
|
+
onAttachment?: (attachment: unknown) => void;
|
|
27
|
+
onError?: (error: ChatError) => void;
|
|
28
|
+
onDone?: (meta?: ChatCompletion) => void;
|
|
29
|
+
};
|
|
30
|
+
export type ChatCompletion = {
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
};
|
|
33
|
+
export type ChatTransportInput = {
|
|
34
|
+
message: string;
|
|
35
|
+
history: ChatMessageData[];
|
|
36
|
+
sessionId: string | null;
|
|
37
|
+
signal: AbortSignal;
|
|
38
|
+
};
|
|
39
|
+
export type ChatTransport = (input: ChatTransportInput, handlers: ChatStreamHandlers) => Promise<void>;
|
|
40
|
+
export type ChatControllerOptions = {
|
|
41
|
+
transport: ChatTransport;
|
|
42
|
+
initialMessages?: ChatMessageData[];
|
|
43
|
+
typewriter?: boolean;
|
|
44
|
+
generateId?: () => string;
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|