@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.
Files changed (73) hide show
  1. package/dist/{CkInput.vue_vue_type_script_setup_true_lang-CyGLItQZ.js → CkInput.vue_vue_type_script_setup_true_lang-C5C09u0z.js} +9 -8
  2. package/dist/adapters/index.d.ts +18 -0
  3. package/dist/adapters/index.d.ts.map +1 -0
  4. package/dist/adapters/index.js +4 -0
  5. package/dist/adapters/responses-api.d.ts +180 -0
  6. package/dist/adapters/responses-api.d.ts.map +1 -0
  7. package/dist/adapters/responses-api.js +153 -0
  8. package/dist/components/base/CkPromptActionButton/CkPromptActionButton.vue.d.ts +1 -1
  9. package/dist/components/composed/CkConversation/CkConversation.stories.d.ts +11 -3
  10. package/dist/components/composed/CkConversation/CkConversation.stories.d.ts.map +1 -1
  11. package/dist/components/composed/CkConversation/CkConversation.vue.d.ts +5 -1
  12. package/dist/components/composed/CkConversation/CkConversation.vue.d.ts.map +1 -1
  13. package/dist/components/index.js +1 -1
  14. package/dist/composables/fileUpload/index.d.ts +7 -0
  15. package/dist/composables/fileUpload/index.d.ts.map +1 -0
  16. package/dist/composables/fileUpload/types.d.ts +295 -0
  17. package/dist/composables/fileUpload/types.d.ts.map +1 -0
  18. package/dist/composables/fileUpload/useFileUpload.d.ts +4 -0
  19. package/dist/composables/fileUpload/useFileUpload.d.ts.map +1 -0
  20. package/dist/composables/fileUpload/useFileUploadWrapper.d.ts +3 -0
  21. package/dist/composables/fileUpload/useFileUploadWrapper.d.ts.map +1 -0
  22. package/dist/composables/index.d.ts +2 -1
  23. package/dist/composables/index.d.ts.map +1 -1
  24. package/dist/composables/index.js +5 -2
  25. package/dist/composables/useConversations.d.ts +12 -0
  26. package/dist/composables/useConversations.d.ts.map +1 -1
  27. package/dist/generateId-BHf0W4Rq.js +6 -0
  28. package/dist/handlers/index.js +1 -1
  29. package/dist/handlers/useMessageHandler.d.ts +2 -2
  30. package/dist/handlers/useMessageHandler.d.ts.map +1 -1
  31. package/dist/index-BbTgIoYa.js +1557 -0
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +6 -8
  35. package/dist/services/index.d.ts +0 -2
  36. package/dist/services/index.d.ts.map +1 -1
  37. package/dist/services/index.js +1 -37
  38. package/dist/services/types.d.ts +2 -2
  39. package/dist/services/types.d.ts.map +1 -1
  40. package/dist/types.d.ts +47 -2
  41. package/dist/types.d.ts.map +1 -1
  42. package/dist/{useMessageHandler-BmBdu2EW.js → useMessageHandler-ZRC-gIOJ.js} +5 -5
  43. package/package.json +10 -2
  44. package/src/adapters/index.ts +17 -0
  45. package/src/adapters/responses-api.spec.ts +365 -0
  46. package/src/adapters/responses-api.ts +444 -0
  47. package/src/components/composed/CkConversation/CkConversation.spec.ts +171 -25
  48. package/src/components/composed/CkConversation/CkConversation.stories.ts +266 -46
  49. package/src/components/composed/CkConversation/CkConversation.vue +19 -7
  50. package/src/composables/fileUpload/index.spec.ts +213 -0
  51. package/src/composables/fileUpload/index.ts +83 -0
  52. package/src/composables/fileUpload/types.ts +409 -0
  53. package/src/composables/fileUpload/useFileUpload.ts +1242 -0
  54. package/src/composables/fileUpload/useFileUploadWrapper.ts +382 -0
  55. package/src/composables/index.ts +2 -1
  56. package/src/composables/useConversations.spec.ts +118 -0
  57. package/src/composables/useConversations.ts +32 -0
  58. package/src/handlers/useChatKitLabels.spec.ts +16 -2
  59. package/src/handlers/useMessageHandler.spec.ts +112 -44
  60. package/src/handlers/useMessageHandler.ts +16 -2
  61. package/src/helpers/conversationTree.spec.ts +46 -19
  62. package/src/index.ts +11 -2
  63. package/src/services/index.ts +0 -2
  64. package/src/services/types.ts +2 -2
  65. package/src/types.ts +55 -2
  66. package/dist/ChatService-LogwJNxh.js +0 -9
  67. package/dist/services/ChatService.d.ts +0 -42
  68. package/dist/services/ChatService.d.ts.map +0 -1
  69. package/dist/services/MockChatService.d.ts +0 -10
  70. package/dist/services/MockChatService.d.ts.map +0 -1
  71. package/dist/useConversationSessions-ulFhtpQr.js +0 -243
  72. package/src/services/ChatService.ts +0 -60
  73. package/src/services/MockChatService.ts +0 -47
@@ -0,0 +1,213 @@
1
+ import {
2
+ defaultDocumentUploadConfig,
3
+ createDocumentUploadProvider,
4
+ } from './index';
5
+ import type { DocumentUploadConfig } from './types';
6
+
7
+ vi.mock('./useFileUploadWrapper', () => ({
8
+ createDocumentUploadProvider: vi.fn((config: DocumentUploadConfig) => ({
9
+ useDocumentUpload: vi.fn(() => ({
10
+ upload: {},
11
+ storeId: { value: '' },
12
+ fileInput: { value: null },
13
+ uploadFiles: vi.fn(),
14
+ unassignedFiles: { value: [] },
15
+ assignFilesToMessage: vi.fn(),
16
+ getFilesForMessage: vi.fn(() => []),
17
+ stampResponseId: vi.fn(),
18
+ purgeCompletedFiles: vi.fn(),
19
+ handleFilesSelected: vi.fn(),
20
+ })),
21
+ _config: config,
22
+ })),
23
+ }));
24
+
25
+ describe('fileUpload index', () => {
26
+ describe('defaultDocumentUploadConfig', () => {
27
+ it('uses the correct base URL', () => {
28
+ expect(defaultDocumentUploadConfig.baseUrl).toBe('/file-upload');
29
+ });
30
+
31
+ it('uses the correct userId', () => {
32
+ expect(defaultDocumentUploadConfig.userId).toBe('chat-user');
33
+ });
34
+
35
+ it('uses the correct workflowId', () => {
36
+ expect(defaultDocumentUploadConfig.workflowId).toBe('my-doc-ai');
37
+ });
38
+
39
+ it('configures searchStoreConfig with a dense model', () => {
40
+ const { searchStoreConfig } = defaultDocumentUploadConfig;
41
+ expect(searchStoreConfig.models).toHaveLength(1);
42
+ expect(searchStoreConfig.models[0]).toEqual({
43
+ type: 'dense',
44
+ dimension: 1024,
45
+ distance: 'cosine',
46
+ modality: 'text',
47
+ embedding_model: 'baai/bge-m3',
48
+ });
49
+ });
50
+
51
+ it('configures searchStoreConfig with rrf fusion strategy', () => {
52
+ expect(
53
+ defaultDocumentUploadConfig.searchStoreConfig.fusion_strategy,
54
+ ).toEqual({
55
+ type: 'rrf',
56
+ });
57
+ });
58
+
59
+ it('configures workflowConfig with the correct workflow name', () => {
60
+ const { workflowConfig } = defaultDocumentUploadConfig;
61
+ expect(workflowConfig.name).toBe('my-doc-ai');
62
+ expect(workflowConfig.workflow_name).toBe('DocumentAI');
63
+ });
64
+
65
+ it('configures workflowConfig definition', () => {
66
+ const { workflowConfig } = defaultDocumentUploadConfig;
67
+ expect(workflowConfig.definition).toEqual({
68
+ workflow_name: 'DocumentAI',
69
+ });
70
+ });
71
+
72
+ it('configures initialization parameters', () => {
73
+ const params = defaultDocumentUploadConfig.workflowConfig
74
+ .parameters as Record<string, unknown>;
75
+ expect(params.initialization).toEqual({
76
+ store: { batch_size: 10, pages_per_part: 25 },
77
+ });
78
+ });
79
+
80
+ it('configures all document extraction readers', () => {
81
+ const params = defaultDocumentUploadConfig.workflowConfig
82
+ .parameters as Record<string, unknown>;
83
+ const extraction = params.document_extraction as Record<string, unknown>;
84
+
85
+ expect(extraction.pdf_reader).toEqual({ kind: 'pypdf', batch_size: 10 });
86
+ expect(extraction.docx_reader).toEqual({
87
+ kind: 'docx',
88
+ batch_size: 10,
89
+ split_by_sections: false,
90
+ });
91
+ expect(extraction.pptx_reader).toEqual({
92
+ kind: 'pptx',
93
+ batch_size: 10,
94
+ include_notes: true,
95
+ });
96
+ expect(extraction.xlsx_reader).toEqual({
97
+ kind: 'xlsx',
98
+ batch_size: 10,
99
+ max_rows: 10000,
100
+ max_cols: 100,
101
+ include_empty_sheets: false,
102
+ });
103
+ expect(extraction.markdown_reader).toEqual({
104
+ kind: 'markdown',
105
+ batch_size: 10,
106
+ });
107
+ expect(extraction.plaintext_reader).toEqual({
108
+ kind: 'plaintext',
109
+ batch_size: 10,
110
+ max_content_size: 500000,
111
+ min_space_ratio: 0.02,
112
+ });
113
+ });
114
+
115
+ it('configures chunk extraction parameters', () => {
116
+ const params = defaultDocumentUploadConfig.workflowConfig
117
+ .parameters as Record<string, unknown>;
118
+ const chunkExtraction = params.chunk_extraction as Record<
119
+ string,
120
+ unknown
121
+ >;
122
+ expect(chunkExtraction.chunker).toEqual({
123
+ kind: 'naive',
124
+ batch_size: 1,
125
+ include_image_descriptions: false,
126
+ chunk_size: 200,
127
+ });
128
+ });
129
+
130
+ it('configures workflowConfig schema', () => {
131
+ const { workflowConfig } = defaultDocumentUploadConfig;
132
+ expect(workflowConfig.schema).toEqual({
133
+ type: 'object',
134
+ properties: {
135
+ source: {
136
+ description: 'Source path, connector URI, or list thereof',
137
+ anyOf: [
138
+ { type: 'string' },
139
+ { type: 'array', items: { type: 'string' } },
140
+ ],
141
+ },
142
+ },
143
+ additionalProperties: true,
144
+ });
145
+ });
146
+ });
147
+
148
+ describe('createDocumentUploadProvider', () => {
149
+ it('is re-exported from useFileUploadWrapper', () => {
150
+ expect(createDocumentUploadProvider).toBeDefined();
151
+ expect(typeof createDocumentUploadProvider).toBe('function');
152
+ });
153
+
154
+ it('returns a provider with useDocumentUpload', () => {
155
+ const provider = createDocumentUploadProvider(
156
+ defaultDocumentUploadConfig,
157
+ );
158
+ expect(provider).toHaveProperty('useDocumentUpload');
159
+ expect(typeof provider.useDocumentUpload).toBe('function');
160
+ });
161
+
162
+ it('passes the config to createDocumentUploadProvider', () => {
163
+ const customConfig: DocumentUploadConfig = {
164
+ baseUrl: '/custom-url',
165
+ userId: 'custom-user',
166
+ workflowId: 'custom-workflow',
167
+ searchStoreConfig: {
168
+ models: [
169
+ {
170
+ type: 'dense',
171
+ dimension: 512,
172
+ distance: 'euclidean',
173
+ modality: 'text',
174
+ embedding_model: 'custom-model',
175
+ },
176
+ ],
177
+ fusion_strategy: { type: 'custom' },
178
+ },
179
+ workflowConfig: { name: 'custom' },
180
+ };
181
+
182
+ const provider = createDocumentUploadProvider(
183
+ customConfig,
184
+ ) as unknown as {
185
+ useDocumentUpload: () => unknown;
186
+ _config: DocumentUploadConfig;
187
+ };
188
+ expect(provider._config).toBe(customConfig);
189
+ });
190
+ });
191
+
192
+ describe('useDocumentUploadWithDefaultConfig', () => {
193
+ it('is exported and callable', async () => {
194
+ const { useDocumentUploadWithDefaultConfig } = await import('./index');
195
+ expect(useDocumentUploadWithDefaultConfig).toBeDefined();
196
+ expect(typeof useDocumentUploadWithDefaultConfig).toBe('function');
197
+ });
198
+ });
199
+
200
+ describe('type exports', () => {
201
+ it('exports DocumentUploadConfig type', async () => {
202
+ const module = await import('./index');
203
+ expect('defaultDocumentUploadConfig' in module).toBe(true);
204
+ });
205
+
206
+ it('exports DocumentUploadProvider type via createDocumentUploadProvider', () => {
207
+ const provider = createDocumentUploadProvider(
208
+ defaultDocumentUploadConfig,
209
+ );
210
+ expect(provider).toBeDefined();
211
+ });
212
+ });
213
+ });
@@ -0,0 +1,83 @@
1
+ import type { DocumentUploadConfig, DocumentUploadProvider } from './types';
2
+ import { createDocumentUploadProvider } from './useFileUploadWrapper';
3
+
4
+ const WORKFLOW_ID = 'my-doc-ai';
5
+
6
+ export const defaultDocumentUploadConfig: DocumentUploadConfig = {
7
+ baseUrl: '/file-upload',
8
+ userId: 'chat-user',
9
+ workflowId: WORKFLOW_ID,
10
+ searchStoreConfig: {
11
+ models: [
12
+ {
13
+ type: 'dense',
14
+ dimension: 1024,
15
+ distance: 'cosine',
16
+ modality: 'text',
17
+ embedding_model: 'baai/bge-m3',
18
+ },
19
+ ],
20
+ fusion_strategy: { type: 'rrf' },
21
+ },
22
+ workflowConfig: {
23
+ name: WORKFLOW_ID,
24
+ workflow_name: 'DocumentAI',
25
+ definition: { workflow_name: 'DocumentAI' },
26
+ parameters: {
27
+ initialization: {
28
+ store: { batch_size: 10, pages_per_part: 25 },
29
+ },
30
+ document_extraction: {
31
+ pdf_reader: { kind: 'pypdf', batch_size: 10 },
32
+ docx_reader: {
33
+ kind: 'docx',
34
+ batch_size: 10,
35
+ split_by_sections: false,
36
+ },
37
+ pptx_reader: { kind: 'pptx', batch_size: 10, include_notes: true },
38
+ xlsx_reader: {
39
+ kind: 'xlsx',
40
+ batch_size: 10,
41
+ max_rows: 10000,
42
+ max_cols: 100,
43
+ include_empty_sheets: false,
44
+ },
45
+ markdown_reader: { kind: 'markdown', batch_size: 10 },
46
+ plaintext_reader: {
47
+ kind: 'plaintext',
48
+ batch_size: 10,
49
+ max_content_size: 500000,
50
+ min_space_ratio: 0.02,
51
+ },
52
+ },
53
+ chunk_extraction: {
54
+ chunker: {
55
+ kind: 'naive',
56
+ batch_size: 1,
57
+ include_image_descriptions: false,
58
+ chunk_size: 200,
59
+ },
60
+ },
61
+ },
62
+ schema: {
63
+ type: 'object',
64
+ properties: {
65
+ source: {
66
+ description: 'Source path, connector URI, or list thereof',
67
+ anyOf: [
68
+ { type: 'string' },
69
+ { type: 'array', items: { type: 'string' } },
70
+ ],
71
+ },
72
+ },
73
+ additionalProperties: true,
74
+ },
75
+ },
76
+ };
77
+
78
+ const { useDocumentUpload: useDocumentUploadWithDefaultConfig } =
79
+ createDocumentUploadProvider(defaultDocumentUploadConfig);
80
+
81
+ export { useDocumentUploadWithDefaultConfig, createDocumentUploadProvider };
82
+
83
+ export type { DocumentUploadConfig, DocumentUploadProvider };
@@ -0,0 +1,409 @@
1
+ import type { ComputedRef, MaybeRef, Ref } from 'vue';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // HTTP Client
5
+ // ---------------------------------------------------------------------------
6
+
7
+ export interface RequestConfig {
8
+ signal?: AbortSignal;
9
+ onUploadProgress?: (event: { loaded: number; total: number }) => void;
10
+ }
11
+
12
+ export interface SseEvent {
13
+ event: string;
14
+ data: string;
15
+ }
16
+
17
+ export interface SseStream {
18
+ subscribe(callback: (event: SseEvent) => void): void;
19
+ close(): void;
20
+ }
21
+
22
+ export interface HttpClient {
23
+ get<T>(url: string, config?: RequestConfig): Promise<T>;
24
+ post<T>(url: string, body: unknown, config?: RequestConfig): Promise<T>;
25
+ delete<T>(url: string, config?: RequestConfig): Promise<T>;
26
+ stream(url: string, config?: RequestConfig): SseStream;
27
+ }
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Endpoint Resolver
31
+ // ---------------------------------------------------------------------------
32
+
33
+ export interface EndpointResolver {
34
+ files: (storeId: string) => string;
35
+ file: (storeId: string, fileId: string) => string;
36
+ filePublicUrl: (storeId: string, fileId: string) => string;
37
+ workflowRun: (storeId: string, workflowId: string) => string;
38
+ workflowRunEventStream: (
39
+ storeId: string,
40
+ workflowId: string,
41
+ runId: string,
42
+ ) => string;
43
+ }
44
+
45
+ export const defaultEndpoints: EndpointResolver = {
46
+ files: (storeId) => `search-stores/${storeId}/files`,
47
+ file: (storeId, fileId) => `search-stores/${storeId}/files/${fileId}`,
48
+ filePublicUrl: (storeId, fileId) =>
49
+ `search-stores/${storeId}/files/${fileId}/public-urls?ttl=1h`,
50
+ workflowRun: (storeId, workflowId) =>
51
+ `search-stores/${storeId}/workflows/${workflowId}/runs`,
52
+ workflowRunEventStream: (storeId, workflowId, runId) =>
53
+ `search-stores/${storeId}/workflows/${workflowId}/runs/${runId}/event-stream`,
54
+ };
55
+
56
+ // ---------------------------------------------------------------------------
57
+ // Domain Models
58
+ // ---------------------------------------------------------------------------
59
+
60
+ export interface RemoteFile {
61
+ id: string;
62
+ name: string;
63
+ size: number;
64
+ mime_type: string;
65
+ created_at: string;
66
+ updated_at: string;
67
+ metadata: Record<string, unknown>;
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // File Constraints & Validation
72
+ // ---------------------------------------------------------------------------
73
+
74
+ export interface FileConstraints {
75
+ allowedMimeTypes: string[];
76
+ allowedExtensions: string[];
77
+ maxFileSizeBytes: number;
78
+ maxFilesPerUpload: number;
79
+ }
80
+
81
+ export type ValidatorFn = (
82
+ file: File,
83
+ constraints: FileConstraints,
84
+ ) => ValidationResult | Promise<ValidationResult>;
85
+
86
+ export interface ValidationResult {
87
+ valid: boolean;
88
+ reason?: string;
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // File State
93
+ // ---------------------------------------------------------------------------
94
+
95
+ export type FileStatus =
96
+ | 'queued'
97
+ | 'validating'
98
+ | 'uploading'
99
+ | 'processing'
100
+ | 'success'
101
+ | 'failed'
102
+ | 'cancelled'
103
+ | 'removing'
104
+ | 'removed';
105
+
106
+ export type ThumbnailStrategy = 'canvas' | 'icon-fallback';
107
+
108
+ export interface FileThumbnail {
109
+ dataUrl: string;
110
+ width: number;
111
+ height: number;
112
+ generatedAt: string;
113
+ strategy: ThumbnailStrategy;
114
+ }
115
+
116
+ export interface FileUploadError {
117
+ code: string;
118
+ message: string;
119
+ httpStatus?: number;
120
+ details?: unknown;
121
+ occurredAt: string;
122
+ }
123
+
124
+ export interface FileEntry {
125
+ id: string;
126
+ groupId: string;
127
+ fileName: string;
128
+ fileSize: number;
129
+ fileType: string;
130
+
131
+ status: FileStatus;
132
+ progress: number;
133
+
134
+ queuedAt: string;
135
+ uploadStartedAt: string | null;
136
+ uploadCompletedAt: string | null;
137
+ cancelledAt: string | null;
138
+ removedAt: string | null;
139
+
140
+ uploadDurationMs: number | null;
141
+ remoteFileId: string | null;
142
+ error: FileUploadError | null;
143
+
144
+ attemptCount: number;
145
+ lastAttemptAt: string | null;
146
+
147
+ thumbnail: FileThumbnail | null;
148
+ metadata: Record<string, unknown>;
149
+ }
150
+
151
+ export type FileStateMap = Map<string, FileEntry>;
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // Upload
155
+ // ---------------------------------------------------------------------------
156
+
157
+ export interface UploadParams {
158
+ id: string;
159
+ files: File | File[];
160
+ metadata?: Record<string, unknown>;
161
+ forwardedProps?: Record<string, unknown>;
162
+ signal?: AbortSignal;
163
+ }
164
+
165
+ export interface UploadResult {
166
+ id: string;
167
+ results: UploadFileResult[];
168
+ }
169
+
170
+ export interface UploadFileResult {
171
+ fileId: string;
172
+ success: boolean;
173
+ status: FileStatus;
174
+ remoteFileId?: string;
175
+ error?: FileUploadError;
176
+ uploadDate: string;
177
+ metadata?: Record<string, unknown>;
178
+ }
179
+
180
+ // ---------------------------------------------------------------------------
181
+ // File Removal
182
+ // ---------------------------------------------------------------------------
183
+
184
+ export interface RemoveFileOptions {
185
+ removeFromState?: boolean;
186
+ removeFromRemote?: boolean;
187
+ }
188
+
189
+ // ---------------------------------------------------------------------------
190
+ // Retry
191
+ // ---------------------------------------------------------------------------
192
+
193
+ export interface RetryPolicy {
194
+ maxRetries: number;
195
+ delayMs: number;
196
+ backoffMultiplier?: number;
197
+ retryableStatusCodes?: number[];
198
+ }
199
+
200
+ // ---------------------------------------------------------------------------
201
+ // Persistence
202
+ // ---------------------------------------------------------------------------
203
+
204
+ export interface PersistOptions {
205
+ dbName?: string;
206
+ storeName?: string;
207
+ debounceMs?: number;
208
+ maxAge?: number;
209
+ filter?: (entry: FileEntry) => boolean;
210
+ }
211
+
212
+ // ---------------------------------------------------------------------------
213
+ // Events
214
+ // ---------------------------------------------------------------------------
215
+
216
+ export type UploadEvent =
217
+ | { type: 'file:queued'; fileId: string; entry: FileEntry }
218
+ | { type: 'file:validating'; fileId: string }
219
+ | { type: 'file:uploading'; fileId: string; attemptCount: number }
220
+ | { type: 'file:progress'; fileId: string; progress: number }
221
+ | {
222
+ type: 'file:success';
223
+ fileId: string;
224
+ remoteFileId: string;
225
+ durationMs: number;
226
+ }
227
+ | { type: 'file:failed'; fileId: string; error: FileUploadError }
228
+ | { type: 'file:cancelled'; fileId: string }
229
+ | { type: 'file:removed'; fileId: string }
230
+ | { type: 'file:thumbnail-failed'; fileId: string; reason: string }
231
+ | { type: 'upload:complete'; groupId: string; results: UploadFileResult[] }
232
+ | { type: 'workflow:started'; runId: string }
233
+ | { type: 'workflow:event'; event: WorkflowRunEvent }
234
+ | { type: 'workflow:completed'; runId: string }
235
+ | {
236
+ type: 'workflow:failed';
237
+ runId: string;
238
+ error: { code: string; message: string };
239
+ }
240
+ | { type: 'state:restored'; entryCount: number }
241
+ | { type: 'state:persisted'; entryCount: number }
242
+ | { type: 'state:persist-error'; error: Error };
243
+
244
+ // ---------------------------------------------------------------------------
245
+ // Scoped View
246
+ // ---------------------------------------------------------------------------
247
+
248
+ export interface ScopedFileView {
249
+ files: ComputedRef<FileEntry[]>;
250
+ count: ComputedRef<number>;
251
+ progress: ComputedRef<number>;
252
+ isUploading: ComputedRef<boolean>;
253
+ hasErrors: ComputedRef<boolean>;
254
+ clear: () => void;
255
+ cancel: () => void;
256
+ retry: (fileId: string) => void;
257
+ }
258
+
259
+ // ---------------------------------------------------------------------------
260
+ // Workflow
261
+ // ---------------------------------------------------------------------------
262
+
263
+ export interface WorkflowRunInput {
264
+ source: string;
265
+ }
266
+
267
+ export type WorkflowRunStatus =
268
+ | 'connecting'
269
+ | 'running'
270
+ | 'completed'
271
+ | 'failed'
272
+ | 'cancelled';
273
+
274
+ export interface WorkflowRunEvent {
275
+ id: string;
276
+ status: string;
277
+ }
278
+
279
+ export interface WorkflowRun {
280
+ runId: string;
281
+ workflowId: string;
282
+ storeId: string;
283
+ status: WorkflowRunStatus;
284
+ events: WorkflowRunEvent[];
285
+ error: { code: string; message: string } | null;
286
+ startedAt: string;
287
+ completedAt: string | null;
288
+ }
289
+
290
+ export interface WorkflowStream {
291
+ close(): void;
292
+ }
293
+
294
+ // ---------------------------------------------------------------------------
295
+ // Error
296
+ // ---------------------------------------------------------------------------
297
+
298
+ export type ErrorCode =
299
+ | 'NO_ACTIVE_STORE'
300
+ | 'STORE_NOT_FOUND'
301
+ | 'FILE_TOO_LARGE'
302
+ | 'FILE_TYPE_NOT_ALLOWED'
303
+ | 'MAX_FILES_EXCEEDED'
304
+ | 'VALIDATION_FAILED'
305
+ | 'UPLOAD_FAILED'
306
+ | 'UPLOAD_ABORTED'
307
+ | 'REMOVE_FAILED'
308
+ | 'WORKFLOW_NOT_FOUND'
309
+ | 'WORKFLOW_RUN_FAILED'
310
+ | 'NETWORK_ERROR'
311
+ | 'UPLOAD_INTERRUPTED'
312
+ | 'REMOVE_INTERRUPTED';
313
+
314
+ export class SdkError extends Error {
315
+ constructor(
316
+ public readonly code: ErrorCode,
317
+ message: string,
318
+ public readonly details?: unknown,
319
+ ) {
320
+ super(message);
321
+ this.name = 'SdkError';
322
+ }
323
+ }
324
+
325
+ // ---------------------------------------------------------------------------
326
+ // Document Upload Provider Config
327
+ // ---------------------------------------------------------------------------
328
+
329
+ export interface SearchStoreModel {
330
+ type: string;
331
+ dimension: number;
332
+ distance: string;
333
+ modality: string;
334
+ embedding_model: string;
335
+ }
336
+
337
+ export interface DocumentUploadConfig {
338
+ baseUrl: string;
339
+ userId: string;
340
+ workflowId: string;
341
+ searchStoreConfig: {
342
+ models: SearchStoreModel[];
343
+ fusion_strategy: Record<string, unknown>;
344
+ };
345
+ workflowConfig: Record<string, unknown>;
346
+ persist?: boolean;
347
+ maxConcurrency?: number;
348
+ headers?: Record<string, string>;
349
+ onEvent?: (event: UploadEvent) => void;
350
+ }
351
+
352
+ export interface DocumentUploadProvider {
353
+ useDocumentUpload: (
354
+ conversationIdRef: MaybeRef<string>,
355
+ ) => DocumentUploadReturn;
356
+ }
357
+
358
+ export interface DocumentUploadReturn {
359
+ upload: UseFileUploadReturn;
360
+ storeId: Ref<string>;
361
+ fileInput: Ref<HTMLInputElement | null>;
362
+ uploadFiles: (files: File[]) => Promise<UploadResult | undefined>;
363
+ unassignedFiles: ComputedRef<FileEntry[]>;
364
+ assignFilesToMessage: (messageId: string) => void;
365
+ getFilesForMessage: (messageId: string) => FileEntry[];
366
+ stampResponseId: (responseId: string, localMessageId: string) => void;
367
+ purgeCompletedFiles: () => void;
368
+ handleFilesSelected: (event: Event) => void;
369
+ }
370
+
371
+ // ---------------------------------------------------------------------------
372
+ // Composable Options & Return
373
+ // ---------------------------------------------------------------------------
374
+
375
+ export interface UseFileUploadOptions {
376
+ client: HttpClient;
377
+ storeId?: string;
378
+ workflowId: string;
379
+ endpoints?: EndpointResolver;
380
+ persist?: PersistOptions | boolean;
381
+ maxConcurrency?: number;
382
+ retryPolicy?: RetryPolicy;
383
+ validators?: ValidatorFn[];
384
+ onEvent?: (event: UploadEvent) => void;
385
+ }
386
+
387
+ export interface UseFileUploadReturn {
388
+ getSupportedFileTypes: () => FileConstraints;
389
+
390
+ upload: (params: UploadParams) => Promise<UploadResult>;
391
+ cancel: (groupId: string) => void;
392
+ removeFile: (fileId: string, options?: RemoveFileOptions) => Promise<void>;
393
+
394
+ files: Ref<FileStateMap>;
395
+ getFileState: (id: string) => FileEntry | undefined;
396
+ updateFileMetadata: (id: string, meta: Record<string, unknown>) => void;
397
+ clearState: () => void;
398
+ setStoreId: (id: string) => void;
399
+ getPublicUrl: (fileId: string) => Promise<string>;
400
+
401
+ scopeBy: (metadataKey: string, value: string) => ScopedFileView;
402
+
403
+ workflowRun: Ref<WorkflowRun | null>;
404
+ runWorkflow: (fileIds: string[]) => Promise<WorkflowStream>;
405
+
406
+ isRestoring: Ref<boolean>;
407
+ restoreState: () => Promise<void>;
408
+ purgePersistedState: () => Promise<void>;
409
+ }