@aleph-alpha/chat-kit 1.4.0 → 1.5.1

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.
@@ -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
+ }