@aleph-alpha/chat-kit 1.3.1 → 1.5.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-CyGLItQZ.js → CkInput.vue_vue_type_script_setup_true_lang-C5C09u0z.js} +9 -8
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +4 -0
- package/dist/adapters/responses-api.d.ts +180 -0
- package/dist/adapters/responses-api.d.ts.map +1 -0
- package/dist/adapters/responses-api.js +153 -0
- package/dist/components/base/CkPromptActionButton/CkPromptActionButton.vue.d.ts +1 -1
- package/dist/components/composed/CkConversation/CkConversation.stories.d.ts +11 -3
- package/dist/components/composed/CkConversation/CkConversation.stories.d.ts.map +1 -1
- package/dist/components/composed/CkConversation/CkConversation.vue.d.ts +5 -1
- package/dist/components/composed/CkConversation/CkConversation.vue.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/composables/fileUpload/index.d.ts +7 -0
- package/dist/composables/fileUpload/index.d.ts.map +1 -0
- package/dist/composables/fileUpload/types.d.ts +295 -0
- package/dist/composables/fileUpload/types.d.ts.map +1 -0
- package/dist/composables/fileUpload/useFileUpload.d.ts +4 -0
- package/dist/composables/fileUpload/useFileUpload.d.ts.map +1 -0
- package/dist/composables/fileUpload/useFileUploadWrapper.d.ts +3 -0
- package/dist/composables/fileUpload/useFileUploadWrapper.d.ts.map +1 -0
- package/dist/composables/index.d.ts +2 -1
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/index.js +5 -2
- package/dist/composables/useConversations.d.ts +12 -0
- package/dist/composables/useConversations.d.ts.map +1 -1
- package/dist/generateId-BHf0W4Rq.js +6 -0
- package/dist/handlers/index.js +1 -1
- package/dist/handlers/useMessageHandler.d.ts +2 -2
- package/dist/handlers/useMessageHandler.d.ts.map +1 -1
- package/dist/index-BbTgIoYa.js +1557 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -8
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -37
- package/dist/services/types.d.ts +2 -2
- package/dist/services/types.d.ts.map +1 -1
- package/dist/types.d.ts +47 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/{useMessageHandler-BmBdu2EW.js → useMessageHandler-ZRC-gIOJ.js} +5 -5
- package/package.json +10 -2
- package/src/adapters/index.ts +17 -0
- package/src/adapters/responses-api.spec.ts +365 -0
- package/src/adapters/responses-api.ts +444 -0
- package/src/components/composed/CkConversation/CkConversation.spec.ts +171 -25
- package/src/components/composed/CkConversation/CkConversation.stories.ts +266 -46
- package/src/components/composed/CkConversation/CkConversation.vue +19 -7
- package/src/composables/fileUpload/index.spec.ts +213 -0
- package/src/composables/fileUpload/index.ts +83 -0
- package/src/composables/fileUpload/types.ts +409 -0
- package/src/composables/fileUpload/useFileUpload.ts +1242 -0
- package/src/composables/fileUpload/useFileUploadWrapper.ts +382 -0
- package/src/composables/index.ts +2 -1
- package/src/composables/useConversations.spec.ts +118 -0
- package/src/composables/useConversations.ts +32 -0
- package/src/handlers/useChatKitLabels.spec.ts +16 -2
- package/src/handlers/useMessageHandler.spec.ts +112 -44
- package/src/handlers/useMessageHandler.ts +16 -2
- package/src/helpers/conversationTree.spec.ts +46 -19
- package/src/index.ts +11 -2
- package/src/services/index.ts +0 -2
- package/src/services/types.ts +2 -2
- package/src/types.ts +55 -2
- package/dist/ChatService-LogwJNxh.js +0 -9
- package/dist/services/ChatService.d.ts +0 -42
- package/dist/services/ChatService.d.ts.map +0 -1
- package/dist/services/MockChatService.d.ts +0 -10
- package/dist/services/MockChatService.d.ts.map +0 -1
- package/dist/useConversationSessions-ulFhtpQr.js +0 -243
- package/src/services/ChatService.ts +0 -60
- package/src/services/MockChatService.ts +0 -47
package/src/types.ts
CHANGED
|
@@ -6,10 +6,63 @@ export type MessageRole = 'user' | 'assistant' | 'system';
|
|
|
6
6
|
|
|
7
7
|
export type MessageStatus = 'started' | 'sending' | 'completed' | 'error';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Lifecycle of a single content item inside a message — used to indicate
|
|
11
|
+
* whether a streamed text part is still being produced, has finished, or was
|
|
12
|
+
* cut short. Tool content does not carry a status (it represents a single
|
|
13
|
+
* fired tool call) so it always omits this field.
|
|
14
|
+
*/
|
|
15
|
+
export type MessageContentStatus = 'in_progress' | 'completed' | 'incomplete';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Plain text part of a message. Multiple text parts can appear in a single
|
|
19
|
+
* assistant turn, interleaved with reasoning and tool calls.
|
|
20
|
+
*/
|
|
21
|
+
export interface MessageTextContent {
|
|
22
|
+
type: 'text';
|
|
23
|
+
id: string;
|
|
24
|
+
text: string;
|
|
25
|
+
status: MessageContentStatus;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Tool invocation triggered by the assistant during its turn. Only the tool
|
|
30
|
+
* name is rendered; arguments and results are intentionally outside the
|
|
31
|
+
* UI-facing model and should be tracked by the host application.
|
|
32
|
+
*/
|
|
33
|
+
export interface MessageToolContent {
|
|
34
|
+
type: 'tool';
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Chain-of-thought / reasoning segment produced by the assistant. `text` is
|
|
41
|
+
* the (optional) human-readable trail — populated when the underlying
|
|
42
|
+
* transport exposes reasoning content (`REASONING_MESSAGE_CONTENT` deltas
|
|
43
|
+
* during a live run, `reasoning_text` parts when re-hydrating from the
|
|
44
|
+
* Responses API). Surfaces that only need a "Thinking…" / "Thought"
|
|
45
|
+
* indicator can ignore it and rely on `status` alone.
|
|
46
|
+
*/
|
|
47
|
+
export interface MessageReasoningContent {
|
|
48
|
+
type: 'reasoning';
|
|
49
|
+
id: string;
|
|
50
|
+
text?: string;
|
|
51
|
+
status: MessageContentStatus;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Discriminated union of all content parts that can appear inside a message.
|
|
56
|
+
*/
|
|
57
|
+
export type MessageContent =
|
|
58
|
+
| MessageTextContent
|
|
59
|
+
| MessageToolContent
|
|
60
|
+
| MessageReasoningContent;
|
|
61
|
+
|
|
9
62
|
export interface BaseMessage {
|
|
10
63
|
id: string;
|
|
11
64
|
role: MessageRole;
|
|
12
|
-
content:
|
|
65
|
+
content: MessageContent[];
|
|
13
66
|
createdAt: Date;
|
|
14
67
|
status: MessageStatus;
|
|
15
68
|
siblingIds?: string[];
|
|
@@ -22,7 +75,7 @@ export interface TreeMessage {
|
|
|
22
75
|
childrenIds: string[];
|
|
23
76
|
activeChildIndex: number;
|
|
24
77
|
role: MessageRole;
|
|
25
|
-
content:
|
|
78
|
+
content: MessageContent[];
|
|
26
79
|
status: MessageStatus;
|
|
27
80
|
createdAt: Date;
|
|
28
81
|
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { ChatConfig, ChatMessage, ChatResponse, StreamEvent } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Interface for chat service implementations
|
|
4
|
-
*
|
|
5
|
-
* This is a skeleton interface that defines the contract for chat services.
|
|
6
|
-
* Implementations should provide concrete implementations of these methods.
|
|
7
|
-
*/
|
|
8
|
-
export interface IChatService {
|
|
9
|
-
/**
|
|
10
|
-
* Send a message and receive a response
|
|
11
|
-
* @param message - The message to send
|
|
12
|
-
* @returns Promise resolving to the chat response
|
|
13
|
-
*/
|
|
14
|
-
sendMessage(message: ChatMessage): Promise<ChatResponse>;
|
|
15
|
-
/**
|
|
16
|
-
* Get chat history
|
|
17
|
-
* @param limit - Maximum number of messages to retrieve
|
|
18
|
-
* @returns Promise resolving to an array of messages
|
|
19
|
-
*/
|
|
20
|
-
getHistory(limit?: number): Promise<ChatMessage[]>;
|
|
21
|
-
/**
|
|
22
|
-
* Stream a message response
|
|
23
|
-
* @param message - The message to send
|
|
24
|
-
* @param onEvent - Callback for stream events
|
|
25
|
-
* @returns Promise that resolves when streaming is complete
|
|
26
|
-
*/
|
|
27
|
-
streamMessage(message: ChatMessage, onEvent: (event: StreamEvent) => void): Promise<void>;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Abstract base class for chat service implementations
|
|
31
|
-
*
|
|
32
|
-
* This is a skeleton abstract class that can be extended to create
|
|
33
|
-
* concrete chat service implementations.
|
|
34
|
-
*/
|
|
35
|
-
export declare abstract class ChatService implements IChatService {
|
|
36
|
-
protected config: ChatConfig;
|
|
37
|
-
constructor(config?: ChatConfig);
|
|
38
|
-
abstract sendMessage(message: ChatMessage): Promise<ChatResponse>;
|
|
39
|
-
abstract getHistory(limit?: number): Promise<ChatMessage[]>;
|
|
40
|
-
abstract streamMessage(message: ChatMessage, onEvent: (event: StreamEvent) => void): Promise<void>;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=ChatService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChatService.d.ts","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;;;OAIG;IACH,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEnD;;;;;OAKG;IACH,aAAa,CACX,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;GAKG;AACH,8BAAsB,WAAY,YAAW,YAAY;IACvD,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEjB,MAAM,CAAC,EAAE,UAAU;IAI/B,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IACjE,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAC3D,QAAQ,CAAC,aAAa,CACpB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC;CACjB"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ChatService, type IChatService } from './ChatService';
|
|
2
|
-
import type { ChatMessage, ChatResponse, StreamEvent } from './types';
|
|
3
|
-
export declare class MockChatService extends ChatService implements IChatService {
|
|
4
|
-
constructor();
|
|
5
|
-
sendMessage(message: ChatMessage): Promise<ChatResponse>;
|
|
6
|
-
getHistory(): Promise<ChatMessage[]>;
|
|
7
|
-
streamMessage(message: ChatMessage, onEvent: (event: StreamEvent) => void): Promise<void>;
|
|
8
|
-
private createBaseMessage;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=MockChatService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MockChatService.d.ts","sourceRoot":"","sources":["../../src/services/MockChatService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtE,qBAAa,eAAgB,SAAQ,WAAY,YAAW,YAAY;;IAKhE,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAYxD,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIpC,aAAa,CACjB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC;IAMhB,OAAO,CAAC,iBAAiB;CAY1B"}
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { g as generateId, u as useMessageHandler } from "./useMessageHandler-BmBdu2EW.js";
|
|
2
|
-
import { ref, shallowRef, computed, readonly } from "vue";
|
|
3
|
-
import "./purify.es-md74IFlY.js";
|
|
4
|
-
function secondsToDate(seconds) {
|
|
5
|
-
return new Date(seconds * 1e3);
|
|
6
|
-
}
|
|
7
|
-
function toError(value) {
|
|
8
|
-
return value instanceof Error ? value : new Error(String(value));
|
|
9
|
-
}
|
|
10
|
-
function useChat() {
|
|
11
|
-
}
|
|
12
|
-
const DEFAULT_PAGE_SIZE = 20;
|
|
13
|
-
function useConversations(options) {
|
|
14
|
-
const http = options.httpClient;
|
|
15
|
-
const path = options.path;
|
|
16
|
-
const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;
|
|
17
|
-
const conversations = ref([]);
|
|
18
|
-
const inflightCount = shallowRef(0);
|
|
19
|
-
const isLoading = computed(() => inflightCount.value > 0);
|
|
20
|
-
const hasMore = shallowRef(false);
|
|
21
|
-
const error = shallowRef(null);
|
|
22
|
-
let nextCursor = null;
|
|
23
|
-
function beginRequest() {
|
|
24
|
-
inflightCount.value++;
|
|
25
|
-
error.value = null;
|
|
26
|
-
}
|
|
27
|
-
function endRequest() {
|
|
28
|
-
inflightCount.value--;
|
|
29
|
-
}
|
|
30
|
-
async function fetchPage(params) {
|
|
31
|
-
const query = {
|
|
32
|
-
limit: params.limit,
|
|
33
|
-
order: "desc"
|
|
34
|
-
};
|
|
35
|
-
if (params.cursor) query.after = params.cursor;
|
|
36
|
-
const raw = await http.get(path, { params: query });
|
|
37
|
-
return mapConversationList(raw);
|
|
38
|
-
}
|
|
39
|
-
async function fetch(opts) {
|
|
40
|
-
beginRequest();
|
|
41
|
-
try {
|
|
42
|
-
const page = await fetchPage({
|
|
43
|
-
limit: opts?.limit ?? pageSize,
|
|
44
|
-
cursor: null
|
|
45
|
-
});
|
|
46
|
-
conversations.value = page.items;
|
|
47
|
-
nextCursor = page.nextCursor;
|
|
48
|
-
hasMore.value = page.nextCursor !== null;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
error.value = toError(e);
|
|
51
|
-
throw error.value;
|
|
52
|
-
} finally {
|
|
53
|
-
endRequest();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async function fetchMore() {
|
|
57
|
-
if (!hasMore.value || nextCursor === null) return;
|
|
58
|
-
beginRequest();
|
|
59
|
-
try {
|
|
60
|
-
const page = await fetchPage({ limit: pageSize, cursor: nextCursor });
|
|
61
|
-
conversations.value = [...conversations.value, ...page.items];
|
|
62
|
-
nextCursor = page.nextCursor;
|
|
63
|
-
hasMore.value = page.nextCursor !== null;
|
|
64
|
-
} catch (e) {
|
|
65
|
-
error.value = toError(e);
|
|
66
|
-
throw error.value;
|
|
67
|
-
} finally {
|
|
68
|
-
endRequest();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
async function fetchById(id) {
|
|
72
|
-
beginRequest();
|
|
73
|
-
try {
|
|
74
|
-
const raw = await http.get(`${path}/${id}`);
|
|
75
|
-
return mapConversation(raw);
|
|
76
|
-
} catch (e) {
|
|
77
|
-
error.value = toError(e);
|
|
78
|
-
throw error.value;
|
|
79
|
-
} finally {
|
|
80
|
-
endRequest();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async function create(input, opts) {
|
|
84
|
-
const metadata = { ...input?.metadata ?? {} };
|
|
85
|
-
if (input?.title !== void 0) metadata.title = input.title;
|
|
86
|
-
const body = { metadata };
|
|
87
|
-
const previous = conversations.value;
|
|
88
|
-
let placeholder = null;
|
|
89
|
-
if (opts?.optimistic) {
|
|
90
|
-
placeholder = makePlaceholder(input?.title);
|
|
91
|
-
conversations.value = [placeholder, ...previous];
|
|
92
|
-
}
|
|
93
|
-
beginRequest();
|
|
94
|
-
try {
|
|
95
|
-
const raw = await http.post(path, body);
|
|
96
|
-
const created = mapConversation(raw);
|
|
97
|
-
conversations.value = placeholder ? conversations.value.map(
|
|
98
|
-
(c) => c.id === placeholder.id ? created : c
|
|
99
|
-
) : [created, ...conversations.value];
|
|
100
|
-
return created;
|
|
101
|
-
} catch (e) {
|
|
102
|
-
if (placeholder) conversations.value = previous;
|
|
103
|
-
error.value = toError(e);
|
|
104
|
-
throw error.value;
|
|
105
|
-
} finally {
|
|
106
|
-
endRequest();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async function rename(id, title, opts) {
|
|
110
|
-
const previous = conversations.value;
|
|
111
|
-
if (opts?.optimistic) {
|
|
112
|
-
conversations.value = previous.map(
|
|
113
|
-
(c) => c.id === id ? { ...c, title, updatedAt: /* @__PURE__ */ new Date() } : c
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
beginRequest();
|
|
117
|
-
try {
|
|
118
|
-
const raw = await http.post(`${path}/${id}`, {
|
|
119
|
-
metadata: { title }
|
|
120
|
-
});
|
|
121
|
-
const updated = mapConversation(raw);
|
|
122
|
-
conversations.value = conversations.value.map(
|
|
123
|
-
(c) => c.id === id ? updated : c
|
|
124
|
-
);
|
|
125
|
-
return updated;
|
|
126
|
-
} catch (e) {
|
|
127
|
-
if (opts?.optimistic) conversations.value = previous;
|
|
128
|
-
error.value = toError(e);
|
|
129
|
-
throw error.value;
|
|
130
|
-
} finally {
|
|
131
|
-
endRequest();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
async function remove(id, opts) {
|
|
135
|
-
const previous = conversations.value;
|
|
136
|
-
if (opts?.optimistic) {
|
|
137
|
-
conversations.value = previous.filter((c) => c.id !== id);
|
|
138
|
-
}
|
|
139
|
-
beginRequest();
|
|
140
|
-
try {
|
|
141
|
-
await http.delete(`${path}/${id}`);
|
|
142
|
-
if (!opts?.optimistic) {
|
|
143
|
-
conversations.value = previous.filter((c) => c.id !== id);
|
|
144
|
-
}
|
|
145
|
-
} catch (e) {
|
|
146
|
-
if (opts?.optimistic) conversations.value = previous;
|
|
147
|
-
error.value = toError(e);
|
|
148
|
-
throw error.value;
|
|
149
|
-
} finally {
|
|
150
|
-
endRequest();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
function getById(id) {
|
|
154
|
-
return conversations.value.find((c) => c.id === id);
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
conversations: readonly(conversations),
|
|
158
|
-
isLoading,
|
|
159
|
-
hasMore: readonly(hasMore),
|
|
160
|
-
error: readonly(error),
|
|
161
|
-
fetch,
|
|
162
|
-
fetchMore,
|
|
163
|
-
fetchById,
|
|
164
|
-
create,
|
|
165
|
-
rename,
|
|
166
|
-
remove,
|
|
167
|
-
getById
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function mapConversation(raw) {
|
|
171
|
-
return {
|
|
172
|
-
id: raw.id,
|
|
173
|
-
title: raw.metadata?.title ?? "",
|
|
174
|
-
createdAt: secondsToDate(raw.created_at),
|
|
175
|
-
updatedAt: secondsToDate(raw.updated_at)
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
function mapConversationList(raw) {
|
|
179
|
-
return {
|
|
180
|
-
items: raw.data.map(mapConversation),
|
|
181
|
-
nextCursor: raw.has_more ? raw.last_id ?? null : null
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
function makePlaceholder(title) {
|
|
185
|
-
const now = /* @__PURE__ */ new Date();
|
|
186
|
-
return {
|
|
187
|
-
id: `pending-${generateId()}`,
|
|
188
|
-
title: title ?? "",
|
|
189
|
-
createdAt: now,
|
|
190
|
-
updatedAt: now
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
function useConversationSessions() {
|
|
194
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
195
|
-
const focusedId = ref(null);
|
|
196
|
-
function createSession(conversationId) {
|
|
197
|
-
const existing = sessions.get(conversationId);
|
|
198
|
-
if (existing) return existing;
|
|
199
|
-
const session = {
|
|
200
|
-
id: conversationId,
|
|
201
|
-
messageHandler: useMessageHandler()
|
|
202
|
-
};
|
|
203
|
-
sessions.set(conversationId, session);
|
|
204
|
-
return session;
|
|
205
|
-
}
|
|
206
|
-
function getSession(conversationId) {
|
|
207
|
-
return sessions.get(conversationId);
|
|
208
|
-
}
|
|
209
|
-
function setActiveConversation(conversationId) {
|
|
210
|
-
if (conversationId === null) {
|
|
211
|
-
focusedId.value = null;
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
createSession(conversationId);
|
|
215
|
-
focusedId.value = conversationId;
|
|
216
|
-
}
|
|
217
|
-
function removeSession(conversationId) {
|
|
218
|
-
sessions.delete(conversationId);
|
|
219
|
-
if (focusedId.value === conversationId) {
|
|
220
|
-
focusedId.value = null;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
const activeSession = computed(() => {
|
|
224
|
-
const id = focusedId.value;
|
|
225
|
-
return id !== null ? sessions.get(id) ?? null : null;
|
|
226
|
-
});
|
|
227
|
-
const messageHandler = computed(
|
|
228
|
-
() => activeSession.value?.messageHandler ?? null
|
|
229
|
-
);
|
|
230
|
-
return {
|
|
231
|
-
activeSession,
|
|
232
|
-
messageHandler,
|
|
233
|
-
createSession,
|
|
234
|
-
getSession,
|
|
235
|
-
setActiveConversation,
|
|
236
|
-
removeSession
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
export {
|
|
240
|
-
useConversationSessions as a,
|
|
241
|
-
useConversations as b,
|
|
242
|
-
useChat as u
|
|
243
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ChatConfig,
|
|
3
|
-
ChatMessage,
|
|
4
|
-
ChatResponse,
|
|
5
|
-
StreamEvent,
|
|
6
|
-
} from './types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Interface for chat service implementations
|
|
10
|
-
*
|
|
11
|
-
* This is a skeleton interface that defines the contract for chat services.
|
|
12
|
-
* Implementations should provide concrete implementations of these methods.
|
|
13
|
-
*/
|
|
14
|
-
export interface IChatService {
|
|
15
|
-
/**
|
|
16
|
-
* Send a message and receive a response
|
|
17
|
-
* @param message - The message to send
|
|
18
|
-
* @returns Promise resolving to the chat response
|
|
19
|
-
*/
|
|
20
|
-
sendMessage(message: ChatMessage): Promise<ChatResponse>;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get chat history
|
|
24
|
-
* @param limit - Maximum number of messages to retrieve
|
|
25
|
-
* @returns Promise resolving to an array of messages
|
|
26
|
-
*/
|
|
27
|
-
getHistory(limit?: number): Promise<ChatMessage[]>;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Stream a message response
|
|
31
|
-
* @param message - The message to send
|
|
32
|
-
* @param onEvent - Callback for stream events
|
|
33
|
-
* @returns Promise that resolves when streaming is complete
|
|
34
|
-
*/
|
|
35
|
-
streamMessage(
|
|
36
|
-
message: ChatMessage,
|
|
37
|
-
onEvent: (event: StreamEvent) => void,
|
|
38
|
-
): Promise<void>;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Abstract base class for chat service implementations
|
|
43
|
-
*
|
|
44
|
-
* This is a skeleton abstract class that can be extended to create
|
|
45
|
-
* concrete chat service implementations.
|
|
46
|
-
*/
|
|
47
|
-
export abstract class ChatService implements IChatService {
|
|
48
|
-
protected config: ChatConfig;
|
|
49
|
-
|
|
50
|
-
constructor(config?: ChatConfig) {
|
|
51
|
-
this.config = config || {};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
abstract sendMessage(message: ChatMessage): Promise<ChatResponse>;
|
|
55
|
-
abstract getHistory(limit?: number): Promise<ChatMessage[]>;
|
|
56
|
-
abstract streamMessage(
|
|
57
|
-
message: ChatMessage,
|
|
58
|
-
onEvent: (event: StreamEvent) => void,
|
|
59
|
-
): Promise<void>;
|
|
60
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { BaseMessage } from '../types';
|
|
2
|
-
import { ChatService, type IChatService } from './ChatService';
|
|
3
|
-
import type { ChatMessage, ChatResponse, StreamEvent } from './types';
|
|
4
|
-
|
|
5
|
-
export class MockChatService extends ChatService implements IChatService {
|
|
6
|
-
constructor() {
|
|
7
|
-
super({});
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
async sendMessage(message: ChatMessage): Promise<ChatResponse> {
|
|
11
|
-
const replyText = `Mock reply: ${message.content}`;
|
|
12
|
-
|
|
13
|
-
return {
|
|
14
|
-
message: this.createBaseMessage({
|
|
15
|
-
role: 'assistant',
|
|
16
|
-
content: replyText,
|
|
17
|
-
}),
|
|
18
|
-
metadata: { mock: true },
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async getHistory(): Promise<ChatMessage[]> {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async streamMessage(
|
|
27
|
-
message: ChatMessage,
|
|
28
|
-
onEvent: (event: StreamEvent) => void,
|
|
29
|
-
): Promise<void> {
|
|
30
|
-
const response = await this.sendMessage(message);
|
|
31
|
-
onEvent({ type: 'chunk', data: response.message.content });
|
|
32
|
-
onEvent({ type: 'done' });
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private createBaseMessage(input: {
|
|
36
|
-
role: BaseMessage['role'];
|
|
37
|
-
content: string;
|
|
38
|
-
}): BaseMessage {
|
|
39
|
-
return {
|
|
40
|
-
id: crypto.randomUUID(),
|
|
41
|
-
role: input.role,
|
|
42
|
-
content: input.content,
|
|
43
|
-
createdAt: new Date(),
|
|
44
|
-
status: 'completed',
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|